mirror of
https://github.com/Hommy-master/capcut-mate.git
synced 2026-08-28 23:27:50 +08:00
165 lines
5.8 KiB
Python
165 lines
5.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Generate effect_title lists and inject them into add_effects docs."""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from src.pyJianYingDraft.metadata import VideoSceneEffectType, VideoCharacterEffectType
|
|
|
|
MARKER_START = "<!-- EFFECT_LIST_START -->"
|
|
MARKER_END = "<!-- EFFECT_LIST_END -->"
|
|
|
|
EXAMPLE_EFFECT = "录制边框 III"
|
|
EXAMPLE_EFFECT_2 = "简约边框"
|
|
|
|
|
|
def _all_effect_names() -> list[str]:
|
|
names = {item.value.name for item in VideoSceneEffectType} | {
|
|
item.value.name for item in VideoCharacterEffectType
|
|
}
|
|
return sorted(names, key=lambda s: (s.casefold(), s))
|
|
|
|
|
|
def _validate(names: list[str]) -> None:
|
|
scene = {item.value.name for item in VideoSceneEffectType}
|
|
char = {item.value.name for item in VideoCharacterEffectType}
|
|
known = scene | char
|
|
bad = [n for n in names if n not in known]
|
|
if bad:
|
|
raise SystemExit(f"unresolvable effects: {bad[:10]}")
|
|
for example in (EXAMPLE_EFFECT, EXAMPLE_EFFECT_2):
|
|
if example not in known:
|
|
raise SystemExit(f"example effect unresolved: {example}")
|
|
|
|
|
|
def build_zh(names: list[str]) -> str:
|
|
scene_count = len({item.value.name for item in VideoSceneEffectType})
|
|
char_count = len({item.value.name for item in VideoCharacterEffectType})
|
|
return "\n".join(
|
|
[
|
|
"### 支持的特效名称(effect_title 可用值)",
|
|
"",
|
|
"下列名称可直接作为 `effect_title` 的值(与剪映特效展示名一致,来自画面特效与人物特效)。未匹配到时添加会失败。",
|
|
"",
|
|
f"当前共 **{len(names)}** 种(画面特效 {scene_count} + 人物特效 {char_count},去重后):",
|
|
"",
|
|
"```text",
|
|
*names,
|
|
"```",
|
|
"",
|
|
]
|
|
)
|
|
|
|
|
|
def build_en(names: list[str]) -> str:
|
|
scene_count = len({item.value.name for item in VideoSceneEffectType})
|
|
char_count = len({item.value.name for item in VideoCharacterEffectType})
|
|
return "\n".join(
|
|
[
|
|
"### Supported Effect Names (`effect_title` values)",
|
|
"",
|
|
"Use the names below directly as `effect_title` (same as CapCut/Jianying display names; from scene effects and character effects). Unmatched names will fail.",
|
|
"",
|
|
f"Total: **{len(names)}** effects ({scene_count} scene + {char_count} character, after dedupe):",
|
|
"",
|
|
"```text",
|
|
*names,
|
|
"```",
|
|
"",
|
|
]
|
|
)
|
|
|
|
|
|
def inject(path: Path, before: str, block: str) -> None:
|
|
text = path.read_text(encoding="utf-8")
|
|
wrapped = f"{MARKER_START}\n{block.rstrip()}\n{MARKER_END}\n\n"
|
|
|
|
if MARKER_START in text and MARKER_END in text:
|
|
start = text.index(MARKER_START)
|
|
end = text.index(MARKER_END) + len(MARKER_END)
|
|
after = text[end:].lstrip("\n")
|
|
text = text[:start] + wrapped.rstrip("\n") + "\n\n" + after
|
|
else:
|
|
if before not in text:
|
|
raise SystemExit(f"insert marker not found in {path}: {before}")
|
|
text = text.replace(before, wrapped + before, 1)
|
|
|
|
path.write_text(text, encoding="utf-8")
|
|
|
|
|
|
def polish_zh(path: Path) -> None:
|
|
text = path.read_text(encoding="utf-8")
|
|
text = text.replace(
|
|
"[中文版](./add_audios.zh.md) | [English](./add_audios.md)",
|
|
"[中文版](./add_effects.zh.md) | [English](./add_effects.md)",
|
|
)
|
|
text = text.replace(
|
|
'- `effect_title`: 特效名称,必须是系统中已存在的特效名称',
|
|
'- `effect_title`: 特效名称,须为下方「支持的特效名称」列表中的值',
|
|
)
|
|
# Replace outdated vague name section with pointer (kept until marker replaces area)
|
|
old_section = """#### 特效名称说明
|
|
|
|
- **effect_title**: 特效的名称
|
|
- 格式:字符串
|
|
- 示例:`"录制边框 III"`
|
|
- 获取方式:通过剪映特效库或相关API获取
|
|
- 常见特效名称:
|
|
- 边框特效:"录制边框 III", "简约边框", "霓虹边框"
|
|
- 滤镜特效:"复古滤镜", "黑白滤镜", "暖色调"
|
|
- 动态特效:"粒子效果", "光晕效果", "闪烁特效"
|
|
- 转场特效:"淡入淡出", "推拉门", "马赛克转场"
|
|
|
|
"""
|
|
if old_section in text and MARKER_START not in text:
|
|
text = text.replace(old_section, "")
|
|
elif old_section in text:
|
|
text = text.replace(old_section, "")
|
|
|
|
text = text.replace('\\"复古滤镜\\"', f'\\"{EXAMPLE_EFFECT_2}\\"')
|
|
text = text.replace('"复古滤镜"', f'"{EXAMPLE_EFFECT_2}"')
|
|
path.write_text(text, encoding="utf-8")
|
|
|
|
|
|
def polish_en(path: Path) -> None:
|
|
text = path.read_text(encoding="utf-8")
|
|
text = text.replace(
|
|
'- `effect_title`: Effect name, must be an existing effect name in the system',
|
|
'- `effect_title`: Effect name; must be one of the Supported Effect Names below',
|
|
)
|
|
# Prefer real CapCut titles in examples
|
|
text = text.replace("Recording Border III", EXAMPLE_EFFECT)
|
|
text = text.replace("Vintage Filter", EXAMPLE_EFFECT_2)
|
|
text = text.replace('\\"Recording Border III\\"', f'\\"{EXAMPLE_EFFECT}\\"')
|
|
text = text.replace('\\"Vintage Filter\\"', f'\\"{EXAMPLE_EFFECT_2}\\"')
|
|
path.write_text(text, encoding="utf-8")
|
|
|
|
|
|
def main() -> None:
|
|
names = _all_effect_names()
|
|
_validate(names)
|
|
docs = ROOT / "docs"
|
|
|
|
zh_path = docs / "add_effects.zh.md"
|
|
en_path = docs / "add_effects.md"
|
|
|
|
polish_zh(zh_path)
|
|
polish_en(en_path)
|
|
|
|
inject(zh_path, "## 响应格式", build_zh(names))
|
|
inject(en_path, "## Response Format", build_en(names))
|
|
|
|
# Re-run polish for example replacements that may sit after inject target
|
|
polish_zh(zh_path)
|
|
polish_en(en_path)
|
|
|
|
print(f"updated add_effects docs with {len(names)} effect titles")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|