Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@ scenes/
!examples/*.md
!examples/*.py
!rules/*.json

# Keep CTA assets
!assets/*.png
4 changes: 3 additions & 1 deletion SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ md2video/
│ ├── animations/ # Python 动画模板(9种,纯代码无API依赖)
│ ├── prompt_templates/ # 即梦 prompt 模板 + 预算控制
│ └── storyboard/ # 文章→分镜 AI 拆解器(规则驱动)
├── assets/ # 静态资源(CTA 二维码等)
│ └── qr.png # 真实微信群二维码(供 CTA endcard 引用)
├── examples/ # 示例
│ ├── example_article.md
│ └── example_pipeline.py
Expand Down Expand Up @@ -262,7 +264,7 @@ storyboard_from_article(
3. **音频拼接唯一可靠路径**:mp3 → wav → concat → m4a
4. **禁止使用 emoji**:使用 ASCII 替代(! / X / √)或 Pillow 矢量图形
5. **预算控制**:即梦素材消耗积分,内置 `budget_limit` 和重试限制
6. **二维码资源治理**:CTA 二维码必须注册到 cta_resources.json,生成即校验,URL 与主题一致
6. **二维码资源治理**:CTA 二维码必须注册到 `cta_resources.json`,生成即校验,URL 与主题一致。仓库已预置 `assets/qr.png` 真实微信群二维码,可直接用于 CTA endcard
7. **双路径拼接**:concat_engine 自动选择 `-c copy` 快速路径或 `filter_complex` 特效路径,确保质量与性能的平衡

## 文件规范
Expand Down
34 changes: 34 additions & 0 deletions assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# md2video Assets

## CTA 二维码

`qr.png` — 真实微信群二维码(从 md2wechat 仓库复用)

### 用途

作为视频结尾 CTA 卡片的二维码素材,供 `cta_resource.py` / `generate_qr_cta()` 引用。

### 如何更新

如果二维码过期或需要更换:

1. 替换 `assets/qr.png` 为新图片(保持 300×300 以上分辨率)
2. 更新 `cta_resources.json` 中的 `target_url` 为新的群链接
3. 重新运行 harness 校验二维码完整性

### 预注册配置

已在 `cta_resources.json` 中注册为 `cta_qrcode_main`:

```json
{
"id": "cta_qrcode_main",
"resource_type": "qrcode",
"target_url": "wechat://group",
"target_platform": "wechat",
"target_account": "md2video交流群",
"media_path": "assets/qr.png"
}
```

> **注意**:`target_url` 当前为占位符。如需指向具体链接,请替换后更新 checksum。
Binary file added assets/qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions core/cta_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,38 @@ def register(self, resource: CTAResource):
self.resources = [r for r in self.resources if r.id != resource.id]
self.resources.append(resource)

def register_existing_image(
self,
image_path: str,
target_url: str,
target_platform: str,
target_account: str,
resource_id: str = "cta_qrcode_main",
) -> CTAResource:
"""
注册已有图片作为 CTA 二维码资源(如 assets/qr.png)

使用场景:已有真实二维码图片,无需重新生成。
"""
path = Path(image_path)
if not path.exists():
raise FileNotFoundError(f"二维码图片不存在: {image_path}")

resource = CTAResource(
id=resource_id,
resource_type="qrcode",
target_url=target_url,
target_platform=target_platform,
target_account=target_account,
media_path=str(path),
media_type="image",
checksum=self._compute_checksum(target_url),
valid=True,
notes=f"Registered existing image: {path.name}",
)
self.register(resource)
return resource

def get(self, resource_id: str) -> Optional[CTAResource]:
"""按ID获取资源"""
for r in self.resources:
Expand Down
19 changes: 19 additions & 0 deletions cta_resources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "1.0.0",
"resource_count": 1,
"resources": [
{
"id": "cta_qrcode_main",
"resource_type": "qrcode",
"target_url": "wechat://group",
"target_platform": "wechat",
"target_account": "md2video交流群",
"media_path": "assets/qr.png",
"media_type": "image",
"checksum": "e5c8e0e8f8f8e8e8",
"generated_at": "2026-06-07T06:58:00+08:00",
"notes": "从 md2wechat 仓库复用的真实微信群二维码",
"valid": true
}
]
}
Loading