diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a066845 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,86 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + version: + description: '版本号 (例如 1.5.16)' + required: true + type: string + +jobs: + build-macos: + name: Build macOS (Universal) + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-apple-darwin,aarch64-apple-darwin + + - name: Install dependencies + working-directory: tauri-app + run: npm ci + + - name: Build macOS Universal + working-directory: tauri-app + run: npm run tauri -- build --target universal-apple-darwin + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: macos-universal + path: | + tauri-app/src-tauri/target/universal-apple-darwin/release/bundle/dmg/*.dmg + tauri-app/src-tauri/target/universal-apple-darwin/release/bundle/macos/*.app + + build-windows: + name: Build Windows (x64) + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + - name: Install dependencies + working-directory: tauri-app + run: npm ci + + - name: Build Windows x64 + working-directory: tauri-app + shell: pwsh + run: npm run tauri -- build --target x86_64-pc-windows-msvc + env: + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: windows-x64 + path: | + tauri-app/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe + tauri-app/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi diff --git a/.gitignore b/.gitignore index 6c31ebf..a8d73d9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ __pycache__/ test_kick.sh .playwright-mcp/ *.seed_materials_cache.json +tauri-app/src-tauri/binaries/* +.tauri-signing-key diff --git a/docs/github-actions-release.md b/docs/github-actions-release.md new file mode 100644 index 0000000..66aecaf --- /dev/null +++ b/docs/github-actions-release.md @@ -0,0 +1,153 @@ +# GitHub Actions 发版方案(免费双平台构建) + +> 利用 GitHub Actions 免费的 macOS + Windows runner,实现零成本的双平台自动构建。 + +--- + +## 一、方案优势 + +| 对比项 | GitLab CI(原有) | GitHub Actions(新方案) | +|--------|------------------|------------------------| +| macOS runner | 需要自维护 Mac 物理机 | ✅ GitHub 免费提供(`macos-latest`) | +| Windows runner | 需要自维护 Windows 物理机 | ✅ GitHub 免费提供(`windows-latest`) | +| 并发构建 | 依赖 runner 在线状态 | ✅ 随时触发,并行执行 | +| 产物保留 | 30 天(可配置) | 90 天(默认) | +| 成本 | 维护 runner 硬件/电费 | ✅ 公有仓库完全免费 | + +--- + +## 二、前置准备 + +### 2.1 确认代码已推送到 GitHub + +GitHub Actions 只能构建 **GitHub 仓库**中的代码。如果你的代码只在 GitLab,需要: + +```bash +# 在 GitHub 创建空仓库,然后添加远程地址 +git remote add github https://github.com/你的用户名/美家卡智影.git +git push github master +git push github --tags +``` + +### 2.2 配置 GitHub Secrets(只需做一次) + +进入 GitHub 仓库 → **Settings → Secrets and variables → Actions → New repository secret** + +| Secret 名称 | 值 | 说明 | +|------------|-----|------| +| `TAURI_SIGNING_PRIVATE_KEY` | `dW50cnVzdGVk...`(私钥完整内容) | Tauri updater 签名私钥 | +| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | (留空,不创建) | 若私钥有密码则填,当前无密码 | + +> 私钥从 `tauri-app/.tauri-signing-key` 文件中复制全部内容。 + +--- + +## 三、触发构建的两种方式 + +### 方式一:推送 Git tag(推荐,用于正式发版) + +```bash +# 1. 更新版本号 +python scripts/bump-version.py 1.5.16 + +# 2. 提交并推送 +git add -A +git commit -m "release: v1.5.16" +git push github master + +# 3. 推送 tag 自动触发 GitHub Actions +git tag v1.5.16 +git push github v1.5.16 +``` + +推送 tag 后,GitHub Actions 自动开始构建: +- `build-macos`:在 `macos-latest` runner 上构建 Universal `.dmg` +- `build-windows`:在 `windows-latest` runner 上构建 `.exe` + `.msi` + +### 方式二:手动触发(用于测试或紧急打包) + +进入 GitHub 仓库 → **Actions → Release → Run workflow** +- 输入版本号(如 `1.5.16`) +- 点击 **Run workflow** + +--- + +## 四、获取构建产物 + +构建完成后(约 10-20 分钟): + +1. 进入 GitHub 仓库 → **Actions** +2. 点击最新的 workflow run +3. 页面底部 **Artifacts** 区域下载: + - `macos-universal` → 包含 `.dmg` 和 `.app` + - `windows-x64` → 包含 `.exe` 和 `.msi` + +--- + +## 五、发布更新包(手动执行) + +下载产物后,解压到本地目录,执行发版脚本: + +```bash +# 1. 创建产物目录结构 +mkdir -p bundle/macos +mkdir -p bundle/dmg +mkdir -p bundle/nsis +mkdir -p bundle/msi + +# 2. 将下载的 artifact 解压并放入对应目录 +# macos-universal.zip → bundle/dmg/xxx.dmg, bundle/macos/xxx.app +# windows-x64.zip → bundle/nsis/xxx.exe, bundle/msi/xxx.msi + +# 3. 执行发版脚本 +cd python-api +python scripts/publish_release.py \ + --version 1.5.16 \ + --notes "修复视频导出崩溃\n优化启动速度" \ + --bundle-dir ../bundle +``` + +--- + +## 六、注意事项 + +### 6.1 macOS 签名 +GitHub Actions 的 `macos-latest` runner **没有 Apple Developer 证书**,构建出的 `.app`/`.dmg` 与本地构建一样,是未签名的。用户在首次打开时仍需手动允许。 + +**后续升级**:购买 Apple Developer Program 后,在 workflow 中添加: +```yaml +env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} +``` + +### 6.2 Windows 签名 +同理,未配置 `WINDOWS_CERTIFICATE` 时,`.exe` 会有 SmartScreen 提示。购买证书后配置 GitHub Secrets 即可自动签名。 + +### 6.3 产物自动上传到 Release(可选进阶) + +如需让 GitHub 自动创建 Release 页面并上传产物,可在 workflow 末尾添加: + +```yaml + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: | + tauri-app/src-tauri/target/**/bundle/dmg/*.dmg + tauri-app/src-tauri/target/**/bundle/nsis/*.exe + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + +--- + +## 七、文件清单 + +| 文件 | 作用 | +|------|------| +| `.github/workflows/release.yml` | GitHub Actions 工作流定义 | +| `tauri-app/.tauri-signing-key` | 私钥源文件(本地保存) | +| `tauri-app/src-tauri/tauri.key.pub` | 公钥(已提交 Git) | diff --git a/scripts/check_prompt_category_consistency.py b/scripts/check_prompt_category_consistency.py new file mode 100644 index 0000000..59c345c --- /dev/null +++ b/scripts/check_prompt_category_consistency.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +""" +检查提示词素材库标题与数据库三级分类名的一致性 +""" + +import re +from pathlib import Path +from collections import defaultdict + + +def extract_db_categories(sql_path: str) -> set[str]: + """从 seed_categories.sql 提取所有三级分类 name""" + with open(sql_path, "r", encoding="utf-8") as f: + content = f.read() + + # 匹配 level=3 的 name + matches = re.findall(r"VALUES \('[^']+', '([^']+)', \d+, 3,", content) + return set(matches) + + +def extract_prompt_titles(prompts_dir: str) -> dict[str, list[str]]: + """从提示词文件提取素材库标题""" + results = {} + dir_path = Path(prompts_dir) + + for txt_file in dir_path.rglob("*.txt"): + with open(txt_file, "r", encoding="utf-8") as f: + content = f.read() + + # 查找【内置完整素材库标题】或【内置素材库标题】部分 + marker1 = "【内置完整素材库标题】" + marker2 = "【内置素材库标题】" + + start_idx = -1 + for marker in [marker1, marker2]: + idx = content.find(marker) + if idx != -1: + start_idx = idx + len(marker) + break + + if start_idx == -1: + continue + + # 提取标题列表(到下一个【标记或文件末尾) + section = content[start_idx:] + # 找下一个【标记 + next_marker = section.find("【") + if next_marker != -1: + section = section[:next_marker] + + # 逐行解析,去除空行和注释 + titles = [] + for line in section.strip().split("\n"): + line = line.strip() + if not line or line.startswith("(") or line.startswith("备注"): + continue + # 去除可能的编号前缀如 "1、" 或 "- " + line = re.sub(r"^\d+[、.]\s*", "", line) + line = re.sub(r"^[-•]\s*", "", line) + if line: + titles.append(line) + + if titles: + results[str(txt_file.relative_to(dir_path))] = titles + + return results + + +def normalize_for_compare(text: str) -> str: + """标准化用于比较(去除空格和特殊字符)""" + return re.sub(r"\s+", "", text) + + +def main(): + db_path = Path(__file__).parent.parent / "python-api" / "scripts" / "seed_categories.sql" + prompts_dir = Path(__file__).parent.parent / "python-api" / "app" / "ai" / "prompts" / "system" + + db_categories = extract_db_categories(str(db_path)) + prompt_titles = extract_prompt_titles(str(prompts_dir)) + + print(f"数据库三级分类总数: {len(db_categories)}") + print(f"包含素材库标题的提示词文件数: {len(prompt_titles)}") + print() + + # 汇总所有提示词中的标题 + all_prompt_titles = set() + for file, titles in prompt_titles.items(): + for t in titles: + all_prompt_titles.add(t) + + print(f"提示词中素材库标题总数(去重): {len(all_prompt_titles)}") + print() + + # 对比:提示词中有但数据库中没有的 + in_prompt_not_db = [] + for title in all_prompt_titles: + if title not in db_categories and normalize_for_compare(title) not in {normalize_for_compare(c) for c in db_categories}: + in_prompt_not_db.append(title) + + # 对比:数据库中有但提示词中没有的 + in_db_not_prompt = [] + prompt_normalized = {normalize_for_compare(t) for t in all_prompt_titles} + for cat in db_categories: + if cat not in all_prompt_titles and normalize_for_compare(cat) not in prompt_normalized: + in_db_not_prompt.append(cat) + + # 统计按二级分类分组 + db_by_parent = defaultdict(list) + for cat in db_categories: + # 从分类名推断父分类,如 "卧室原始结构-毛坯基础" → "毛坯基础" + parts = cat.split("-") + if len(parts) >= 2: + parent = parts[-1] + else: + parent = "其他" + db_by_parent[parent].append(cat) + + print("=" * 60) + print("【不一致统计】") + print("=" * 60) + + print(f"\n1. 提示词中有但数据库中无(可能为错误或过时标题): {len(in_prompt_not_db)} 个") + if in_prompt_not_db: + for t in sorted(in_prompt_not_db): + print(f" - {t}") + else: + print(" (无)") + + print(f"\n2. 数据库中有但提示词中无(缺少素材引用): {len(in_db_not_prompt)} 个") + if in_db_not_prompt: + # 按父分类分组 + by_parent = defaultdict(list) + for cat in in_db_not_prompt: + parts = cat.split("-") + parent = parts[-1] if len(parts) >= 2 else "其他" + by_parent[parent].append(cat) + + for parent in sorted(by_parent.keys()): + cats = by_parent[parent] + print(f"\n 【{parent}】({len(cats)}个)") + for cat in sorted(cats): + print(f" - {cat}") + else: + print(" (无)") + + # 统计各提示词文件中的标题数量 + print(f"\n3. 各提示词文件素材库标题数量:") + for file in sorted(prompt_titles.keys()): + titles = prompt_titles[file] + # 计算该文件中与数据库不一致的数量 + mismatched = [t for t in titles if t not in db_categories and normalize_for_compare(t) not in {normalize_for_compare(c) for c in db_categories}] + status = f" ⚠️ 有{mismatched}个不一致" if mismatched else " ✅ 一致" + print(f" {file}: {len(titles)}个标题{status}") + if mismatched: + for m in mismatched: + print(f" ❌ {m}") + + # 总体匹配率 + matched = len(all_prompt_titles) - len(in_prompt_not_db) + match_rate = (matched / len(all_prompt_titles) * 100) if all_prompt_titles else 0 + print(f"\n总体匹配率: {match_rate:.1f}% ({matched}/{len(all_prompt_titles)})") + + +if __name__ == "__main__": + main() diff --git a/scripts/collect_viral_opening.py b/scripts/collect_viral_opening.py new file mode 100644 index 0000000..9313f60 --- /dev/null +++ b/scripts/collect_viral_opening.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +""" +网红开篇素材归集脚本 +==================== + +把所有重命名后的 .mp4 复制到一个统一目录,方便批量上传。 + +用法: + python3 scripts/collect_viral_opening.py + +输出: + /Users/0fun/Desktop/网红开篇_upload/ ← 41 个 mp4 平铺在此 +""" + +import shutil +from pathlib import Path + + +def main(): + src_dir = Path("/Users/0fun/Desktop/网红开篇") + out_dir = Path("/Users/0fun/Desktop/网红开篇_upload") + out_dir.mkdir(exist_ok=True) + + copied = 0 + for mp4_file in sorted(src_dir.rglob("*.mp4")): + if mp4_file.name.startswith("."): + continue + + dest = out_dir / mp4_file.name + shutil.copy2(mp4_file, dest) + copied += 1 + print(f"✓ {mp4_file.name}") + + print(f"\n✅ 共复制 {copied} 个文件到: {out_dir}") + + +if __name__ == "__main__": + main() diff --git a/scripts/import_viral_opening.py b/scripts/import_viral_opening.py new file mode 100644 index 0000000..bae2ddb --- /dev/null +++ b/scripts/import_viral_opening.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +""" +网红开篇素材批量入库脚本 +============================ + +功能: +1. 遍历指定目录下的 .mp4 视频 +2. 按规则 md5(父目录名_原文件名) 生成新文件名 +3. 用 ffprobe 提取视频时长 +4. 生成七牛云上传命令 + 数据库 INSERT SQL + +用法: + cd /Users/0fun/work/meijiaka-zy + python scripts/import_viral_opening.py \ + --src "/Users/0fun/Desktop/网红开篇" \ + --bucket "meijiaka-zy" \ + --prefix "materials" \ + --domain "https://media.liche.cn" + +输出: + - scripts/viral_opening_upload.sh # 七牛云批量上传命令 + - scripts/viral_opening_insert.sql # 数据库 INSERT 语句 +""" + +import argparse +import hashlib +import json +import os +import subprocess +import sys +from pathlib import Path + + +# 目录名 → 三级分类 slug 映射(与 seed_categories.sql 对应) +FOLDER_TO_SLUG = { + "暴力拆除-恶搞开篇": "wanghong-egao-blcc", + "搞笑涂料施工-恶搞开篇": "wanghong-egao-gxtlsg", + "工地恶搞-恶搞开篇": "wanghong-egao-gdeg", + "贴砖恶搞-恶搞开篇": "wanghong-egao-tzeg", + "吸睛画面-恶搞开篇": "wanghong-egao-xjhm", + "炫技-恶搞开篇": "wanghong-egao-xj", + "防水翻车漏水-施工翻车镜": "wanghong-fanche-fsfcls", +} + + +def get_video_duration(filepath: str) -> float | None: + """用 ffmpeg -i 提取视频时长(秒),保留 2 位小数""" + try: + result = subprocess.run( + ["ffmpeg", "-i", filepath], + capture_output=True, + text=True, + timeout=30, + ) + # ffmpeg 把信息输出到 stderr,解析 Duration: 00:00:04.25 + import re + match = re.search(r"Duration:\s+(\d+):(\d+):(\d+\.\d+)", result.stderr) + if match: + hours, minutes, seconds = match.groups() + total = float(hours) * 3600 + float(minutes) * 60 + float(seconds) + return round(total, 2) + except Exception as e: + print(f" ⚠️ 读取时长失败: {e}") + return None + + +def md5_filename(parent_name: str, original_name: str) -> str: + """ + 生成新文件名:md5(父目录名_原文件名).mp4 + + 示例: + 父目录名: 暴力拆除-恶搞开篇 + 原文件名: 5月16日(13).mp4 + 拼接: 暴力拆除-恶搞开篇_5月16日(13).mp4 + md5: a3f7b2c8... (32位十六进制) + 结果: a3f7b2c8....mp4 + """ + raw = f"{parent_name}_{original_name}" + md5_hex = hashlib.md5(raw.encode("utf-8")).hexdigest() + return f"{md5_hex}.mp4" + + +def scan_videos(src_dir: str) -> list[dict]: + """扫描目录,返回视频信息列表""" + videos = [] + src_path = Path(src_dir) + + for mp4_file in sorted(src_path.rglob("*.mp4")): + # 跳过 macOS 系统文件 + if mp4_file.name.startswith("."): + continue + + parent_folder = mp4_file.parent.name + original_name = mp4_file.name + + # 检查分类映射 + slug = FOLDER_TO_SLUG.get(parent_folder) + if not slug: + print(f"⚠️ 未找到分类映射: {parent_folder}/{original_name},跳过") + continue + + new_filename = md5_filename(parent_folder, original_name) + + print(f"📹 处理: {parent_folder}/{original_name} → {new_filename}") + duration = get_video_duration(str(mp4_file)) + if duration is None: + print(f" ❌ 无法读取时长,跳过") + continue + + videos.append({ + "original_path": str(mp4_file), + "parent_folder": parent_folder, + "original_name": original_name, + "new_filename": new_filename, + "slug": slug, + "duration": duration, + }) + + return videos + + +def generate_outputs(videos: list[dict], bucket: str, prefix: str, domain: str) -> None: + """生成上传脚本和入库 SQL""" + script_dir = Path(__file__).parent + + # 1. 生成上传脚本 + upload_script = script_dir / "viral_opening_upload.sh" + with open(upload_script, "w", encoding="utf-8") as f: + f.write("#!/bin/bash\n# 网红开篇素材批量上传脚本\n\n") + for v in videos: + cdn_url = f"{domain}/{bucket}/{prefix}/{v['new_filename']}" + f.write( + f"# {v['parent_folder']}/{v['original_name']} ({v['duration']}s)\n" + f"# qshell put {bucket} {prefix}/{v['new_filename']} " + f"'{v['original_path']}'\n" + f"# 或: qshell fput {bucket} {prefix}/{v['new_filename']} " + f"'{v['original_path']}'\n\n" + ) + os.chmod(upload_script, 0o755) + + # 2. 生成入库 SQL + sql_file = script_dir / "viral_opening_insert.sql" + with open(sql_file, "w", encoding="utf-8") as f: + f.write("-- 网红开篇素材入库 SQL\n") + f.write("-- 共 {} 个视频\n\n".format(len(videos))) + f.write("BEGIN;\n\n") + + for v in videos: + cdn_url = f"{domain}/{bucket}/{prefix}/{v['new_filename']}" + f.write( + "INSERT INTO mjk_broll_materials " + "(category_id, title, url, duration, usage_count, status, created_at, updated_at)\n" + "SELECT id, '{}', '{}', {}, 0, 'active', NOW(), NOW()\n" + "FROM mjk_broll_categories WHERE slug = '{}' AND level = 3;\n".format( + v["new_filename"], + cdn_url, + v["duration"], + v["slug"], + ) + ) + f.write( + "-- 来源: {} | 时长: {}s | 分类: {}\n\n".format( + v["parent_folder"], + v["duration"], + v["slug"], + ) + ) + + f.write("COMMIT;\n") + + # 3. 生成映射 JSON(方便核对) + mapping_file = script_dir / "viral_opening_mapping.json" + with open(mapping_file, "w", encoding="utf-8") as f: + json.dump(videos, f, ensure_ascii=False, indent=2) + + print(f"\n✅ 生成完成:") + print(f" - 上传脚本: {upload_script}") + print(f" - 入库 SQL: {sql_file}") + print(f" - 映射 JSON: {mapping_file}") + + +def main(): + parser = argparse.ArgumentParser(description="网红开篇素材批量入库") + parser.add_argument("--src", default="/Users/0fun/Desktop/网红开篇", help="素材源目录") + parser.add_argument("--bucket", default="meijiaka-zy", help="七牛云 bucket") + parser.add_argument("--prefix", default="materials", help="七牛云路径前缀") + parser.add_argument("--domain", default="https://media.liche.cn", help="CDN 域名") + args = parser.parse_args() + + if not Path(args.src).exists(): + print(f"❌ 目录不存在: {args.src}") + sys.exit(1) + + print(f"🔍 扫描目录: {args.src}\n") + videos = scan_videos(args.src) + + if not videos: + print("❌ 未找到可处理的视频") + sys.exit(1) + + print(f"\n📊 共找到 {len(videos)} 个视频") + generate_outputs(videos, args.bucket, args.prefix, args.domain) + + +if __name__ == "__main__": + main() diff --git a/scripts/rename_viral_opening.py b/scripts/rename_viral_opening.py new file mode 100644 index 0000000..d1c633d --- /dev/null +++ b/scripts/rename_viral_opening.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +""" +网红开篇素材批量重命名脚本 +============================ + +按规则 md5(父目录名_原文件名) 重命名本地视频文件。 + +用法: + python3 scripts/rename_viral_opening.py + +效果: + /Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(13).mp4 + → /Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/2eaf1185....mp4 +""" + +import hashlib +import json +from pathlib import Path + + +def md5_filename(parent_name: str, original_name: str) -> str: + raw = f"{parent_name}_{original_name}" + return hashlib.md5(raw.encode("utf-8")).hexdigest() + ".mp4" + + +def main(): + src_dir = Path("/Users/0fun/Desktop/网红开篇") + renamed = [] + + for mp4_file in sorted(src_dir.rglob("*.mp4")): + if mp4_file.name.startswith("."): + continue + + parent_folder = mp4_file.parent.name + original_name = mp4_file.name + new_name = md5_filename(parent_folder, original_name) + + if mp4_file.name == new_name: + continue # 已经重命名过 + + new_path = mp4_file.parent / new_name + + print(f"{original_name}\n → {new_name}") + mp4_file.rename(new_path) + renamed.append({ + "original": original_name, + "new": new_name, + "folder": parent_folder, + "path": str(new_path), + }) + + print(f"\n✅ 共重命名 {len(renamed)} 个文件") + + # 保存重命名记录 + record = Path(__file__).parent / "viral_opening_renamed.json" + with open(record, "w", encoding="utf-8") as f: + json.dump(renamed, f, ensure_ascii=False, indent=2) + print(f"📄 记录已保存: {record}") + + +if __name__ == "__main__": + main() diff --git a/scripts/viral_opening_insert.sql b/scripts/viral_opening_insert.sql new file mode 100644 index 0000000..b29dd6f --- /dev/null +++ b/scripts/viral_opening_insert.sql @@ -0,0 +1,211 @@ +-- 网红开篇素材入库 SQL +-- 共 41 个视频 + +BEGIN; + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'b3aff6db0536a8d7f51277bd17a449b3.mp4', 'https://media.liche.cn/meijiaka-zy/materials/b3aff6db0536a8d7f51277bd17a449b3.mp4', 4.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 4.02s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '845c6856746752c319239869d03d2def.mp4', 'https://media.liche.cn/meijiaka-zy/materials/845c6856746752c319239869d03d2def.mp4', 4.5, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 4.5s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '4819ccec34b556b6a686503c8496d2d2.mp4', 'https://media.liche.cn/meijiaka-zy/materials/4819ccec34b556b6a686503c8496d2d2.mp4', 9.17, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 9.17s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '2073d7ca41856cc162ac3a86881eeee8.mp4', 'https://media.liche.cn/meijiaka-zy/materials/2073d7ca41856cc162ac3a86881eeee8.mp4', 6.32, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 6.32s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '0097dceb9c7218d66f4b31d9ad47aee3.mp4', 'https://media.liche.cn/meijiaka-zy/materials/0097dceb9c7218d66f4b31d9ad47aee3.mp4', 5.43, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 5.43s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '811ad18d3f8e5cf3792460e4aabf1744.mp4', 'https://media.liche.cn/meijiaka-zy/materials/811ad18d3f8e5cf3792460e4aabf1744.mp4', 5.2, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 5.2s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '7f1ec7aeab78ee64171fa6685c4439fc.mp4', 'https://media.liche.cn/meijiaka-zy/materials/7f1ec7aeab78ee64171fa6685c4439fc.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 8.01s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'df3223bb4de53e197ddd944ed5d2e5d5.mp4', 'https://media.liche.cn/meijiaka-zy/materials/df3223bb4de53e197ddd944ed5d2e5d5.mp4', 8.8, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 8.8s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'a2c9adea107f99cdc5f6fb6b02236579.mp4', 'https://media.liche.cn/meijiaka-zy/materials/a2c9adea107f99cdc5f6fb6b02236579.mp4', 7.11, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 7.11s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'c77b5e546cb0393a5e7c3c4cea3bebb2.mp4', 'https://media.liche.cn/meijiaka-zy/materials/c77b5e546cb0393a5e7c3c4cea3bebb2.mp4', 6.62, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 6.62s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'a29f7c2ffa5a39326d6aed18f0c6df8d.mp4', 'https://media.liche.cn/meijiaka-zy/materials/a29f7c2ffa5a39326d6aed18f0c6df8d.mp4', 5.04, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 5.04s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'e7cc059acaca9d9286c547c1f9f3c39f.mp4', 'https://media.liche.cn/meijiaka-zy/materials/e7cc059acaca9d9286c547c1f9f3c39f.mp4', 5.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xjhm' AND level = 3; +-- 来源: 吸睛画面-恶搞开篇 | 时长: 5.02s | 分类: wanghong-egao-xjhm + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '8c5bbf96530c1a03b9f084d13e06c7c9.mp4', 'https://media.liche.cn/meijiaka-zy/materials/8c5bbf96530c1a03b9f084d13e06c7c9.mp4', 7.34, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 7.34s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '24c662049e2db23c8ad8e39b188d769c.mp4', 'https://media.liche.cn/meijiaka-zy/materials/24c662049e2db23c8ad8e39b188d769c.mp4', 5.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 5.02s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '6f9c760668d743102ae4e6e0943a658f.mp4', 'https://media.liche.cn/meijiaka-zy/materials/6f9c760668d743102ae4e6e0943a658f.mp4', 4.25, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 4.25s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '44622ad5abe2e66279550bc7f95dcc6b.mp4', 'https://media.liche.cn/meijiaka-zy/materials/44622ad5abe2e66279550bc7f95dcc6b.mp4', 6.08, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 6.08s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '4f2290dd81773eaada0a3a0cc8adf115.mp4', 'https://media.liche.cn/meijiaka-zy/materials/4f2290dd81773eaada0a3a0cc8adf115.mp4', 5.04, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 5.04s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '8021088c304e09ac93929660530d68ab.mp4', 'https://media.liche.cn/meijiaka-zy/materials/8021088c304e09ac93929660530d68ab.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 8.01s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'b25deff3d658d6b5e1f82715d5b32e6c.mp4', 'https://media.liche.cn/meijiaka-zy/materials/b25deff3d658d6b5e1f82715d5b32e6c.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 8.01s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '93e95bedaf905e63613d5971ecbde77d.mp4', 'https://media.liche.cn/meijiaka-zy/materials/93e95bedaf905e63613d5971ecbde77d.mp4', 5.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 5.02s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '17705678ad0757af9e70fd1ca4579882.mp4', 'https://media.liche.cn/meijiaka-zy/materials/17705678ad0757af9e70fd1ca4579882.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gdeg' AND level = 3; +-- 来源: 工地恶搞-恶搞开篇 | 时长: 8.01s | 分类: wanghong-egao-gdeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '6ea04c0905384386643a43ad3d8c62e8.mp4', 'https://media.liche.cn/meijiaka-zy/materials/6ea04c0905384386643a43ad3d8c62e8.mp4', 4.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 4.02s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'c1c71478b19779df6d6231c76147c00e.mp4', 'https://media.liche.cn/meijiaka-zy/materials/c1c71478b19779df6d6231c76147c00e.mp4', 4.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 4.02s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'fd03a112a4b9e7edc4534648d17b5cff.mp4', 'https://media.liche.cn/meijiaka-zy/materials/fd03a112a4b9e7edc4534648d17b5cff.mp4', 4.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 4.02s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '70ea7edb5173568fa8079da9fe7da0bf.mp4', 'https://media.liche.cn/meijiaka-zy/materials/70ea7edb5173568fa8079da9fe7da0bf.mp4', 7.34, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 7.34s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '688a3f761f110c7ce320a7a124baf191.mp4', 'https://media.liche.cn/meijiaka-zy/materials/688a3f761f110c7ce320a7a124baf191.mp4', 5.04, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 5.04s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '0750b373b8d293020e593c0fb6ca973b.mp4', 'https://media.liche.cn/meijiaka-zy/materials/0750b373b8d293020e593c0fb6ca973b.mp4', 4.11, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 4.11s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '33a38a924ca3ee44ae651c452b742799.mp4', 'https://media.liche.cn/meijiaka-zy/materials/33a38a924ca3ee44ae651c452b742799.mp4', 5.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-gxtlsg' AND level = 3; +-- 来源: 搞笑涂料施工-恶搞开篇 | 时长: 5.02s | 分类: wanghong-egao-gxtlsg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '2eaf1185874d48136e3fbc62e908d455.mp4', 'https://media.liche.cn/meijiaka-zy/materials/2eaf1185874d48136e3fbc62e908d455.mp4', 4.25, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-blcc' AND level = 3; +-- 来源: 暴力拆除-恶搞开篇 | 时长: 4.25s | 分类: wanghong-egao-blcc + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'd9fe52d52a13c5fcd15736f342f082fe.mp4', 'https://media.liche.cn/meijiaka-zy/materials/d9fe52d52a13c5fcd15736f342f082fe.mp4', 7.62, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-blcc' AND level = 3; +-- 来源: 暴力拆除-恶搞开篇 | 时长: 7.62s | 分类: wanghong-egao-blcc + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'c252875cd6948d0f38062cb07538194d.mp4', 'https://media.liche.cn/meijiaka-zy/materials/c252875cd6948d0f38062cb07538194d.mp4', 6.78, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-blcc' AND level = 3; +-- 来源: 暴力拆除-恶搞开篇 | 时长: 6.78s | 分类: wanghong-egao-blcc + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'dd1cee83a3366ff11bd00df286193d0b.mp4', 'https://media.liche.cn/meijiaka-zy/materials/dd1cee83a3366ff11bd00df286193d0b.mp4', 6.34, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-blcc' AND level = 3; +-- 来源: 暴力拆除-恶搞开篇 | 时长: 6.34s | 分类: wanghong-egao-blcc + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4', 'https://media.liche.cn/meijiaka-zy/materials/e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4', 3.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xj' AND level = 3; +-- 来源: 炫技-恶搞开篇 | 时长: 3.02s | 分类: wanghong-egao-xj + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'a19a83b9a3b5f32daf154a46b457bb69.mp4', 'https://media.liche.cn/meijiaka-zy/materials/a19a83b9a3b5f32daf154a46b457bb69.mp4', 3.55, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xj' AND level = 3; +-- 来源: 炫技-恶搞开篇 | 时长: 3.55s | 分类: wanghong-egao-xj + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '92baf7b9594e89c5f366fb77168a4879.mp4', 'https://media.liche.cn/meijiaka-zy/materials/92baf7b9594e89c5f366fb77168a4879.mp4', 4.02, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xj' AND level = 3; +-- 来源: 炫技-恶搞开篇 | 时长: 4.02s | 分类: wanghong-egao-xj + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, 'a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4', 'https://media.liche.cn/meijiaka-zy/materials/a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4', 5.04, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-xj' AND level = 3; +-- 来源: 炫技-恶搞开篇 | 时长: 5.04s | 分类: wanghong-egao-xj + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '62d4bc30cccf74a3300f40c3952470d3.mp4', 'https://media.liche.cn/meijiaka-zy/materials/62d4bc30cccf74a3300f40c3952470d3.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-tzeg' AND level = 3; +-- 来源: 贴砖恶搞-恶搞开篇 | 时长: 8.01s | 分类: wanghong-egao-tzeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '9a134ff2649212d5f33069c850df385f.mp4', 'https://media.liche.cn/meijiaka-zy/materials/9a134ff2649212d5f33069c850df385f.mp4', 9.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-tzeg' AND level = 3; +-- 来源: 贴砖恶搞-恶搞开篇 | 时长: 9.01s | 分类: wanghong-egao-tzeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '00d6b249ce62c2553a23e3d93e460d91.mp4', 'https://media.liche.cn/meijiaka-zy/materials/00d6b249ce62c2553a23e3d93e460d91.mp4', 8.03, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-egao-tzeg' AND level = 3; +-- 来源: 贴砖恶搞-恶搞开篇 | 时长: 8.03s | 分类: wanghong-egao-tzeg + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '73e70b1aacab4e4ddaa06f361ff1c07e.mp4', 'https://media.liche.cn/meijiaka-zy/materials/73e70b1aacab4e4ddaa06f361ff1c07e.mp4', 8.01, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-fanche-fsfcls' AND level = 3; +-- 来源: 防水翻车漏水-施工翻车镜 | 时长: 8.01s | 分类: wanghong-fanche-fsfcls + +INSERT INTO mjk_broll_materials (category_id, title, url, duration, usage_count, status, created_at, updated_at) +SELECT id, '6d770fb02e2bbb6000b8123fe5a9fb55.mp4', 'https://media.liche.cn/meijiaka-zy/materials/6d770fb02e2bbb6000b8123fe5a9fb55.mp4', 7.5, 0, 'active', NOW(), NOW() +FROM mjk_broll_categories WHERE slug = 'wanghong-fanche-fsfcls' AND level = 3; +-- 来源: 防水翻车漏水-施工翻车镜 | 时长: 7.5s | 分类: wanghong-fanche-fsfcls + +COMMIT; diff --git a/scripts/viral_opening_mapping.json b/scripts/viral_opening_mapping.json new file mode 100644 index 0000000..8fa00a2 --- /dev/null +++ b/scripts/viral_opening_mapping.json @@ -0,0 +1,330 @@ +[ + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(19).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(19).mp4", + "new_filename": "b3aff6db0536a8d7f51277bd17a449b3.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 4.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(23).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(23).mp4", + "new_filename": "845c6856746752c319239869d03d2def.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 4.5 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(24).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(24).mp4", + "new_filename": "4819ccec34b556b6a686503c8496d2d2.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 9.17 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(26).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(26).mp4", + "new_filename": "2073d7ca41856cc162ac3a86881eeee8.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 6.32 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(27).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(27).mp4", + "new_filename": "0097dceb9c7218d66f4b31d9ad47aee3.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 5.43 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(33).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(33).mp4", + "new_filename": "811ad18d3f8e5cf3792460e4aabf1744.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 5.2 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(36).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(36).mp4", + "new_filename": "7f1ec7aeab78ee64171fa6685c4439fc.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(37).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(37).mp4", + "new_filename": "df3223bb4de53e197ddd944ed5d2e5d5.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 8.8 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(38).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(38).mp4", + "new_filename": "a2c9adea107f99cdc5f6fb6b02236579.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 7.11 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(39).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(39).mp4", + "new_filename": "c77b5e546cb0393a5e7c3c4cea3bebb2.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 6.62 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(4).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(4).mp4", + "new_filename": "a29f7c2ffa5a39326d6aed18f0c6df8d.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 5.04 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(8).mp4", + "parent_folder": "吸睛画面-恶搞开篇", + "original_name": "5月16日(8).mp4", + "new_filename": "e7cc059acaca9d9286c547c1f9f3c39f.mp4", + "slug": "wanghong-egao-xjhm", + "duration": 5.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(1).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(1).mp4", + "new_filename": "8c5bbf96530c1a03b9f084d13e06c7c9.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 7.34 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(12).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(12).mp4", + "new_filename": "24c662049e2db23c8ad8e39b188d769c.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 5.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(14).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(14).mp4", + "new_filename": "6f9c760668d743102ae4e6e0943a658f.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 4.25 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(25).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(25).mp4", + "new_filename": "44622ad5abe2e66279550bc7f95dcc6b.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 6.08 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(3).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(3).mp4", + "new_filename": "4f2290dd81773eaada0a3a0cc8adf115.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 5.04 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(34).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(34).mp4", + "new_filename": "8021088c304e09ac93929660530d68ab.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(35).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(35).mp4", + "new_filename": "b25deff3d658d6b5e1f82715d5b32e6c.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(7).mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日(7).mp4", + "new_filename": "93e95bedaf905e63613d5971ecbde77d.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 5.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日.mp4", + "parent_folder": "工地恶搞-恶搞开篇", + "original_name": "5月16日.mp4", + "new_filename": "17705678ad0757af9e70fd1ca4579882.mp4", + "slug": "wanghong-egao-gdeg", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(10).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(10).mp4", + "new_filename": "6ea04c0905384386643a43ad3d8c62e8.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 4.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(11).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(11).mp4", + "new_filename": "c1c71478b19779df6d6231c76147c00e.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 4.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(20).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(20).mp4", + "new_filename": "fd03a112a4b9e7edc4534648d17b5cff.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 4.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(28).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(28).mp4", + "new_filename": "70ea7edb5173568fa8079da9fe7da0bf.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 7.34 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(5).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(5).mp4", + "new_filename": "688a3f761f110c7ce320a7a124baf191.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 5.04 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(6).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(6).mp4", + "new_filename": "0750b373b8d293020e593c0fb6ca973b.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 4.11 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(9).mp4", + "parent_folder": "搞笑涂料施工-恶搞开篇", + "original_name": "5月16日(9).mp4", + "new_filename": "33a38a924ca3ee44ae651c452b742799.mp4", + "slug": "wanghong-egao-gxtlsg", + "duration": 5.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(13).mp4", + "parent_folder": "暴力拆除-恶搞开篇", + "original_name": "5月16日(13).mp4", + "new_filename": "2eaf1185874d48136e3fbc62e908d455.mp4", + "slug": "wanghong-egao-blcc", + "duration": 4.25 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(30).mp4", + "parent_folder": "暴力拆除-恶搞开篇", + "original_name": "5月16日(30).mp4", + "new_filename": "d9fe52d52a13c5fcd15736f342f082fe.mp4", + "slug": "wanghong-egao-blcc", + "duration": 7.62 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(31).mp4", + "parent_folder": "暴力拆除-恶搞开篇", + "original_name": "5月16日(31).mp4", + "new_filename": "c252875cd6948d0f38062cb07538194d.mp4", + "slug": "wanghong-egao-blcc", + "duration": 6.78 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(42).mp4", + "parent_folder": "暴力拆除-恶搞开篇", + "original_name": "5月16日(42).mp4", + "new_filename": "dd1cee83a3366ff11bd00df286193d0b.mp4", + "slug": "wanghong-egao-blcc", + "duration": 6.34 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(15).mp4", + "parent_folder": "炫技-恶搞开篇", + "original_name": "5月16日(15).mp4", + "new_filename": "e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4", + "slug": "wanghong-egao-xj", + "duration": 3.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(16).mp4", + "parent_folder": "炫技-恶搞开篇", + "original_name": "5月16日(16).mp4", + "new_filename": "a19a83b9a3b5f32daf154a46b457bb69.mp4", + "slug": "wanghong-egao-xj", + "duration": 3.55 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(17).mp4", + "parent_folder": "炫技-恶搞开篇", + "original_name": "5月16日(17).mp4", + "new_filename": "92baf7b9594e89c5f366fb77168a4879.mp4", + "slug": "wanghong-egao-xj", + "duration": 4.02 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(22).mp4", + "parent_folder": "炫技-恶搞开篇", + "original_name": "5月16日(22).mp4", + "new_filename": "a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4", + "slug": "wanghong-egao-xj", + "duration": 5.04 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(2).mp4", + "parent_folder": "贴砖恶搞-恶搞开篇", + "original_name": "5月16日(2).mp4", + "new_filename": "62d4bc30cccf74a3300f40c3952470d3.mp4", + "slug": "wanghong-egao-tzeg", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(29).mp4", + "parent_folder": "贴砖恶搞-恶搞开篇", + "original_name": "5月16日(29).mp4", + "new_filename": "9a134ff2649212d5f33069c850df385f.mp4", + "slug": "wanghong-egao-tzeg", + "duration": 9.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(32).mp4", + "parent_folder": "贴砖恶搞-恶搞开篇", + "original_name": "5月16日(32).mp4", + "new_filename": "00d6b249ce62c2553a23e3d93e460d91.mp4", + "slug": "wanghong-egao-tzeg", + "duration": 8.03 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(40).mp4", + "parent_folder": "防水翻车漏水-施工翻车镜", + "original_name": "5月16日(40).mp4", + "new_filename": "73e70b1aacab4e4ddaa06f361ff1c07e.mp4", + "slug": "wanghong-fanche-fsfcls", + "duration": 8.01 + }, + { + "original_path": "/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(41).mp4", + "parent_folder": "防水翻车漏水-施工翻车镜", + "original_name": "5月16日(41).mp4", + "new_filename": "6d770fb02e2bbb6000b8123fe5a9fb55.mp4", + "slug": "wanghong-fanche-fsfcls", + "duration": 7.5 + } +] \ No newline at end of file diff --git a/scripts/viral_opening_renamed.json b/scripts/viral_opening_renamed.json new file mode 100644 index 0000000..1128996 --- /dev/null +++ b/scripts/viral_opening_renamed.json @@ -0,0 +1,248 @@ +[ + { + "original": "5月16日(19).mp4", + "new": "b3aff6db0536a8d7f51277bd17a449b3.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/b3aff6db0536a8d7f51277bd17a449b3.mp4" + }, + { + "original": "5月16日(23).mp4", + "new": "845c6856746752c319239869d03d2def.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/845c6856746752c319239869d03d2def.mp4" + }, + { + "original": "5月16日(24).mp4", + "new": "4819ccec34b556b6a686503c8496d2d2.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/4819ccec34b556b6a686503c8496d2d2.mp4" + }, + { + "original": "5月16日(26).mp4", + "new": "2073d7ca41856cc162ac3a86881eeee8.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/2073d7ca41856cc162ac3a86881eeee8.mp4" + }, + { + "original": "5月16日(27).mp4", + "new": "0097dceb9c7218d66f4b31d9ad47aee3.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/0097dceb9c7218d66f4b31d9ad47aee3.mp4" + }, + { + "original": "5月16日(33).mp4", + "new": "811ad18d3f8e5cf3792460e4aabf1744.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/811ad18d3f8e5cf3792460e4aabf1744.mp4" + }, + { + "original": "5月16日(36).mp4", + "new": "7f1ec7aeab78ee64171fa6685c4439fc.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/7f1ec7aeab78ee64171fa6685c4439fc.mp4" + }, + { + "original": "5月16日(37).mp4", + "new": "df3223bb4de53e197ddd944ed5d2e5d5.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/df3223bb4de53e197ddd944ed5d2e5d5.mp4" + }, + { + "original": "5月16日(38).mp4", + "new": "a2c9adea107f99cdc5f6fb6b02236579.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/a2c9adea107f99cdc5f6fb6b02236579.mp4" + }, + { + "original": "5月16日(39).mp4", + "new": "c77b5e546cb0393a5e7c3c4cea3bebb2.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/c77b5e546cb0393a5e7c3c4cea3bebb2.mp4" + }, + { + "original": "5月16日(4).mp4", + "new": "a29f7c2ffa5a39326d6aed18f0c6df8d.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/a29f7c2ffa5a39326d6aed18f0c6df8d.mp4" + }, + { + "original": "5月16日(8).mp4", + "new": "e7cc059acaca9d9286c547c1f9f3c39f.mp4", + "folder": "吸睛画面-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/e7cc059acaca9d9286c547c1f9f3c39f.mp4" + }, + { + "original": "5月16日(1).mp4", + "new": "8c5bbf96530c1a03b9f084d13e06c7c9.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/8c5bbf96530c1a03b9f084d13e06c7c9.mp4" + }, + { + "original": "5月16日(12).mp4", + "new": "24c662049e2db23c8ad8e39b188d769c.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/24c662049e2db23c8ad8e39b188d769c.mp4" + }, + { + "original": "5月16日(14).mp4", + "new": "6f9c760668d743102ae4e6e0943a658f.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/6f9c760668d743102ae4e6e0943a658f.mp4" + }, + { + "original": "5月16日(25).mp4", + "new": "44622ad5abe2e66279550bc7f95dcc6b.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/44622ad5abe2e66279550bc7f95dcc6b.mp4" + }, + { + "original": "5月16日(3).mp4", + "new": "4f2290dd81773eaada0a3a0cc8adf115.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/4f2290dd81773eaada0a3a0cc8adf115.mp4" + }, + { + "original": "5月16日(34).mp4", + "new": "8021088c304e09ac93929660530d68ab.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/8021088c304e09ac93929660530d68ab.mp4" + }, + { + "original": "5月16日(35).mp4", + "new": "b25deff3d658d6b5e1f82715d5b32e6c.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/b25deff3d658d6b5e1f82715d5b32e6c.mp4" + }, + { + "original": "5月16日(7).mp4", + "new": "93e95bedaf905e63613d5971ecbde77d.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/93e95bedaf905e63613d5971ecbde77d.mp4" + }, + { + "original": "5月16日.mp4", + "new": "17705678ad0757af9e70fd1ca4579882.mp4", + "folder": "工地恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/17705678ad0757af9e70fd1ca4579882.mp4" + }, + { + "original": "5月16日(10).mp4", + "new": "6ea04c0905384386643a43ad3d8c62e8.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/6ea04c0905384386643a43ad3d8c62e8.mp4" + }, + { + "original": "5月16日(11).mp4", + "new": "c1c71478b19779df6d6231c76147c00e.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/c1c71478b19779df6d6231c76147c00e.mp4" + }, + { + "original": "5月16日(20).mp4", + "new": "fd03a112a4b9e7edc4534648d17b5cff.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/fd03a112a4b9e7edc4534648d17b5cff.mp4" + }, + { + "original": "5月16日(28).mp4", + "new": "70ea7edb5173568fa8079da9fe7da0bf.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/70ea7edb5173568fa8079da9fe7da0bf.mp4" + }, + { + "original": "5月16日(5).mp4", + "new": "688a3f761f110c7ce320a7a124baf191.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/688a3f761f110c7ce320a7a124baf191.mp4" + }, + { + "original": "5月16日(6).mp4", + "new": "0750b373b8d293020e593c0fb6ca973b.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/0750b373b8d293020e593c0fb6ca973b.mp4" + }, + { + "original": "5月16日(9).mp4", + "new": "33a38a924ca3ee44ae651c452b742799.mp4", + "folder": "搞笑涂料施工-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/33a38a924ca3ee44ae651c452b742799.mp4" + }, + { + "original": "5月16日(13).mp4", + "new": "2eaf1185874d48136e3fbc62e908d455.mp4", + "folder": "暴力拆除-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/2eaf1185874d48136e3fbc62e908d455.mp4" + }, + { + "original": "5月16日(30).mp4", + "new": "d9fe52d52a13c5fcd15736f342f082fe.mp4", + "folder": "暴力拆除-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/d9fe52d52a13c5fcd15736f342f082fe.mp4" + }, + { + "original": "5月16日(31).mp4", + "new": "c252875cd6948d0f38062cb07538194d.mp4", + "folder": "暴力拆除-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/c252875cd6948d0f38062cb07538194d.mp4" + }, + { + "original": "5月16日(42).mp4", + "new": "dd1cee83a3366ff11bd00df286193d0b.mp4", + "folder": "暴力拆除-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/dd1cee83a3366ff11bd00df286193d0b.mp4" + }, + { + "original": "5月16日(15).mp4", + "new": "e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4", + "folder": "炫技-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4" + }, + { + "original": "5月16日(16).mp4", + "new": "a19a83b9a3b5f32daf154a46b457bb69.mp4", + "folder": "炫技-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/a19a83b9a3b5f32daf154a46b457bb69.mp4" + }, + { + "original": "5月16日(17).mp4", + "new": "92baf7b9594e89c5f366fb77168a4879.mp4", + "folder": "炫技-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/92baf7b9594e89c5f366fb77168a4879.mp4" + }, + { + "original": "5月16日(22).mp4", + "new": "a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4", + "folder": "炫技-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4" + }, + { + "original": "5月16日(2).mp4", + "new": "62d4bc30cccf74a3300f40c3952470d3.mp4", + "folder": "贴砖恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/62d4bc30cccf74a3300f40c3952470d3.mp4" + }, + { + "original": "5月16日(29).mp4", + "new": "9a134ff2649212d5f33069c850df385f.mp4", + "folder": "贴砖恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/9a134ff2649212d5f33069c850df385f.mp4" + }, + { + "original": "5月16日(32).mp4", + "new": "00d6b249ce62c2553a23e3d93e460d91.mp4", + "folder": "贴砖恶搞-恶搞开篇", + "path": "/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/00d6b249ce62c2553a23e3d93e460d91.mp4" + }, + { + "original": "5月16日(40).mp4", + "new": "73e70b1aacab4e4ddaa06f361ff1c07e.mp4", + "folder": "防水翻车漏水-施工翻车镜", + "path": "/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/73e70b1aacab4e4ddaa06f361ff1c07e.mp4" + }, + { + "original": "5月16日(41).mp4", + "new": "6d770fb02e2bbb6000b8123fe5a9fb55.mp4", + "folder": "防水翻车漏水-施工翻车镜", + "path": "/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/6d770fb02e2bbb6000b8123fe5a9fb55.mp4" + } +] \ No newline at end of file diff --git a/scripts/viral_opening_upload.sh b/scripts/viral_opening_upload.sh new file mode 100755 index 0000000..83259f8 --- /dev/null +++ b/scripts/viral_opening_upload.sh @@ -0,0 +1,167 @@ +#!/bin/bash +# 网红开篇素材批量上传脚本 + +# 吸睛画面-恶搞开篇/5月16日(19).mp4 (4.02s) +# qshell put meijiaka-zy materials/b3aff6db0536a8d7f51277bd17a449b3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(19).mp4' +# 或: qshell fput meijiaka-zy materials/b3aff6db0536a8d7f51277bd17a449b3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(19).mp4' + +# 吸睛画面-恶搞开篇/5月16日(23).mp4 (4.5s) +# qshell put meijiaka-zy materials/845c6856746752c319239869d03d2def.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(23).mp4' +# 或: qshell fput meijiaka-zy materials/845c6856746752c319239869d03d2def.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(23).mp4' + +# 吸睛画面-恶搞开篇/5月16日(24).mp4 (9.17s) +# qshell put meijiaka-zy materials/4819ccec34b556b6a686503c8496d2d2.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(24).mp4' +# 或: qshell fput meijiaka-zy materials/4819ccec34b556b6a686503c8496d2d2.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(24).mp4' + +# 吸睛画面-恶搞开篇/5月16日(26).mp4 (6.32s) +# qshell put meijiaka-zy materials/2073d7ca41856cc162ac3a86881eeee8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(26).mp4' +# 或: qshell fput meijiaka-zy materials/2073d7ca41856cc162ac3a86881eeee8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(26).mp4' + +# 吸睛画面-恶搞开篇/5月16日(27).mp4 (5.43s) +# qshell put meijiaka-zy materials/0097dceb9c7218d66f4b31d9ad47aee3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(27).mp4' +# 或: qshell fput meijiaka-zy materials/0097dceb9c7218d66f4b31d9ad47aee3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(27).mp4' + +# 吸睛画面-恶搞开篇/5月16日(33).mp4 (5.2s) +# qshell put meijiaka-zy materials/811ad18d3f8e5cf3792460e4aabf1744.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(33).mp4' +# 或: qshell fput meijiaka-zy materials/811ad18d3f8e5cf3792460e4aabf1744.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(33).mp4' + +# 吸睛画面-恶搞开篇/5月16日(36).mp4 (8.01s) +# qshell put meijiaka-zy materials/7f1ec7aeab78ee64171fa6685c4439fc.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(36).mp4' +# 或: qshell fput meijiaka-zy materials/7f1ec7aeab78ee64171fa6685c4439fc.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(36).mp4' + +# 吸睛画面-恶搞开篇/5月16日(37).mp4 (8.8s) +# qshell put meijiaka-zy materials/df3223bb4de53e197ddd944ed5d2e5d5.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(37).mp4' +# 或: qshell fput meijiaka-zy materials/df3223bb4de53e197ddd944ed5d2e5d5.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(37).mp4' + +# 吸睛画面-恶搞开篇/5月16日(38).mp4 (7.11s) +# qshell put meijiaka-zy materials/a2c9adea107f99cdc5f6fb6b02236579.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(38).mp4' +# 或: qshell fput meijiaka-zy materials/a2c9adea107f99cdc5f6fb6b02236579.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(38).mp4' + +# 吸睛画面-恶搞开篇/5月16日(39).mp4 (6.62s) +# qshell put meijiaka-zy materials/c77b5e546cb0393a5e7c3c4cea3bebb2.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(39).mp4' +# 或: qshell fput meijiaka-zy materials/c77b5e546cb0393a5e7c3c4cea3bebb2.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(39).mp4' + +# 吸睛画面-恶搞开篇/5月16日(4).mp4 (5.04s) +# qshell put meijiaka-zy materials/a29f7c2ffa5a39326d6aed18f0c6df8d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(4).mp4' +# 或: qshell fput meijiaka-zy materials/a29f7c2ffa5a39326d6aed18f0c6df8d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(4).mp4' + +# 吸睛画面-恶搞开篇/5月16日(8).mp4 (5.02s) +# qshell put meijiaka-zy materials/e7cc059acaca9d9286c547c1f9f3c39f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(8).mp4' +# 或: qshell fput meijiaka-zy materials/e7cc059acaca9d9286c547c1f9f3c39f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/吸睛画面-恶搞开篇/5月16日(8).mp4' + +# 工地恶搞-恶搞开篇/5月16日(1).mp4 (7.34s) +# qshell put meijiaka-zy materials/8c5bbf96530c1a03b9f084d13e06c7c9.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(1).mp4' +# 或: qshell fput meijiaka-zy materials/8c5bbf96530c1a03b9f084d13e06c7c9.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(1).mp4' + +# 工地恶搞-恶搞开篇/5月16日(12).mp4 (5.02s) +# qshell put meijiaka-zy materials/24c662049e2db23c8ad8e39b188d769c.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(12).mp4' +# 或: qshell fput meijiaka-zy materials/24c662049e2db23c8ad8e39b188d769c.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(12).mp4' + +# 工地恶搞-恶搞开篇/5月16日(14).mp4 (4.25s) +# qshell put meijiaka-zy materials/6f9c760668d743102ae4e6e0943a658f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(14).mp4' +# 或: qshell fput meijiaka-zy materials/6f9c760668d743102ae4e6e0943a658f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(14).mp4' + +# 工地恶搞-恶搞开篇/5月16日(25).mp4 (6.08s) +# qshell put meijiaka-zy materials/44622ad5abe2e66279550bc7f95dcc6b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(25).mp4' +# 或: qshell fput meijiaka-zy materials/44622ad5abe2e66279550bc7f95dcc6b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(25).mp4' + +# 工地恶搞-恶搞开篇/5月16日(3).mp4 (5.04s) +# qshell put meijiaka-zy materials/4f2290dd81773eaada0a3a0cc8adf115.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(3).mp4' +# 或: qshell fput meijiaka-zy materials/4f2290dd81773eaada0a3a0cc8adf115.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(3).mp4' + +# 工地恶搞-恶搞开篇/5月16日(34).mp4 (8.01s) +# qshell put meijiaka-zy materials/8021088c304e09ac93929660530d68ab.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(34).mp4' +# 或: qshell fput meijiaka-zy materials/8021088c304e09ac93929660530d68ab.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(34).mp4' + +# 工地恶搞-恶搞开篇/5月16日(35).mp4 (8.01s) +# qshell put meijiaka-zy materials/b25deff3d658d6b5e1f82715d5b32e6c.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(35).mp4' +# 或: qshell fput meijiaka-zy materials/b25deff3d658d6b5e1f82715d5b32e6c.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(35).mp4' + +# 工地恶搞-恶搞开篇/5月16日(7).mp4 (5.02s) +# qshell put meijiaka-zy materials/93e95bedaf905e63613d5971ecbde77d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(7).mp4' +# 或: qshell fput meijiaka-zy materials/93e95bedaf905e63613d5971ecbde77d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日(7).mp4' + +# 工地恶搞-恶搞开篇/5月16日.mp4 (8.01s) +# qshell put meijiaka-zy materials/17705678ad0757af9e70fd1ca4579882.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日.mp4' +# 或: qshell fput meijiaka-zy materials/17705678ad0757af9e70fd1ca4579882.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/工地恶搞-恶搞开篇/5月16日.mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(10).mp4 (4.02s) +# qshell put meijiaka-zy materials/6ea04c0905384386643a43ad3d8c62e8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(10).mp4' +# 或: qshell fput meijiaka-zy materials/6ea04c0905384386643a43ad3d8c62e8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(10).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(11).mp4 (4.02s) +# qshell put meijiaka-zy materials/c1c71478b19779df6d6231c76147c00e.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(11).mp4' +# 或: qshell fput meijiaka-zy materials/c1c71478b19779df6d6231c76147c00e.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(11).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(20).mp4 (4.02s) +# qshell put meijiaka-zy materials/fd03a112a4b9e7edc4534648d17b5cff.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(20).mp4' +# 或: qshell fput meijiaka-zy materials/fd03a112a4b9e7edc4534648d17b5cff.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(20).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(28).mp4 (7.34s) +# qshell put meijiaka-zy materials/70ea7edb5173568fa8079da9fe7da0bf.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(28).mp4' +# 或: qshell fput meijiaka-zy materials/70ea7edb5173568fa8079da9fe7da0bf.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(28).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(5).mp4 (5.04s) +# qshell put meijiaka-zy materials/688a3f761f110c7ce320a7a124baf191.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(5).mp4' +# 或: qshell fput meijiaka-zy materials/688a3f761f110c7ce320a7a124baf191.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(5).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(6).mp4 (4.11s) +# qshell put meijiaka-zy materials/0750b373b8d293020e593c0fb6ca973b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(6).mp4' +# 或: qshell fput meijiaka-zy materials/0750b373b8d293020e593c0fb6ca973b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(6).mp4' + +# 搞笑涂料施工-恶搞开篇/5月16日(9).mp4 (5.02s) +# qshell put meijiaka-zy materials/33a38a924ca3ee44ae651c452b742799.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(9).mp4' +# 或: qshell fput meijiaka-zy materials/33a38a924ca3ee44ae651c452b742799.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/搞笑涂料施工-恶搞开篇/5月16日(9).mp4' + +# 暴力拆除-恶搞开篇/5月16日(13).mp4 (4.25s) +# qshell put meijiaka-zy materials/2eaf1185874d48136e3fbc62e908d455.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(13).mp4' +# 或: qshell fput meijiaka-zy materials/2eaf1185874d48136e3fbc62e908d455.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(13).mp4' + +# 暴力拆除-恶搞开篇/5月16日(30).mp4 (7.62s) +# qshell put meijiaka-zy materials/d9fe52d52a13c5fcd15736f342f082fe.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(30).mp4' +# 或: qshell fput meijiaka-zy materials/d9fe52d52a13c5fcd15736f342f082fe.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(30).mp4' + +# 暴力拆除-恶搞开篇/5月16日(31).mp4 (6.78s) +# qshell put meijiaka-zy materials/c252875cd6948d0f38062cb07538194d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(31).mp4' +# 或: qshell fput meijiaka-zy materials/c252875cd6948d0f38062cb07538194d.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(31).mp4' + +# 暴力拆除-恶搞开篇/5月16日(42).mp4 (6.34s) +# qshell put meijiaka-zy materials/dd1cee83a3366ff11bd00df286193d0b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(42).mp4' +# 或: qshell fput meijiaka-zy materials/dd1cee83a3366ff11bd00df286193d0b.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/暴力拆除-恶搞开篇/5月16日(42).mp4' + +# 炫技-恶搞开篇/5月16日(15).mp4 (3.02s) +# qshell put meijiaka-zy materials/e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(15).mp4' +# 或: qshell fput meijiaka-zy materials/e36d1bceeebaadf20ccc5f8dfeb1ab97.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(15).mp4' + +# 炫技-恶搞开篇/5月16日(16).mp4 (3.55s) +# qshell put meijiaka-zy materials/a19a83b9a3b5f32daf154a46b457bb69.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(16).mp4' +# 或: qshell fput meijiaka-zy materials/a19a83b9a3b5f32daf154a46b457bb69.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(16).mp4' + +# 炫技-恶搞开篇/5月16日(17).mp4 (4.02s) +# qshell put meijiaka-zy materials/92baf7b9594e89c5f366fb77168a4879.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(17).mp4' +# 或: qshell fput meijiaka-zy materials/92baf7b9594e89c5f366fb77168a4879.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(17).mp4' + +# 炫技-恶搞开篇/5月16日(22).mp4 (5.04s) +# qshell put meijiaka-zy materials/a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(22).mp4' +# 或: qshell fput meijiaka-zy materials/a2c58cb2c6a1f2c1dec111f2fcefecc8.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/炫技-恶搞开篇/5月16日(22).mp4' + +# 贴砖恶搞-恶搞开篇/5月16日(2).mp4 (8.01s) +# qshell put meijiaka-zy materials/62d4bc30cccf74a3300f40c3952470d3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(2).mp4' +# 或: qshell fput meijiaka-zy materials/62d4bc30cccf74a3300f40c3952470d3.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(2).mp4' + +# 贴砖恶搞-恶搞开篇/5月16日(29).mp4 (9.01s) +# qshell put meijiaka-zy materials/9a134ff2649212d5f33069c850df385f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(29).mp4' +# 或: qshell fput meijiaka-zy materials/9a134ff2649212d5f33069c850df385f.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(29).mp4' + +# 贴砖恶搞-恶搞开篇/5月16日(32).mp4 (8.03s) +# qshell put meijiaka-zy materials/00d6b249ce62c2553a23e3d93e460d91.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(32).mp4' +# 或: qshell fput meijiaka-zy materials/00d6b249ce62c2553a23e3d93e460d91.mp4 '/Users/0fun/Desktop/网红开篇/恶搞开篇/贴砖恶搞-恶搞开篇/5月16日(32).mp4' + +# 防水翻车漏水-施工翻车镜/5月16日(40).mp4 (8.01s) +# qshell put meijiaka-zy materials/73e70b1aacab4e4ddaa06f361ff1c07e.mp4 '/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(40).mp4' +# 或: qshell fput meijiaka-zy materials/73e70b1aacab4e4ddaa06f361ff1c07e.mp4 '/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(40).mp4' + +# 防水翻车漏水-施工翻车镜/5月16日(41).mp4 (7.5s) +# qshell put meijiaka-zy materials/6d770fb02e2bbb6000b8123fe5a9fb55.mp4 '/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(41).mp4' +# 或: qshell fput meijiaka-zy materials/6d770fb02e2bbb6000b8123fe5a9fb55.mp4 '/Users/0fun/Desktop/网红开篇/施工翻车镜/防水翻车漏水-施工翻车镜/5月16日(41).mp4' + diff --git a/tauri-app/docs/windows-signing.md b/tauri-app/docs/windows-signing.md new file mode 100644 index 0000000..a682fd1 --- /dev/null +++ b/tauri-app/docs/windows-signing.md @@ -0,0 +1,124 @@ +# Windows 代码签名配置指南 + +> 本文档说明美家卡智影 Windows 版本的签名机制与配置方法。 + +--- + +## 一、当前状态 + +| 签名类型 | 状态 | 说明 | +|----------|------|------| +| Tauri Updater 自签名 | ✅ 已启用 | 使用 minisign 免费签名,确保自动更新包的完整性 | +| Windows 安装包签名 (NSIS/MSI) | ⏳ 待配置 | 暂未购买商业代码签名证书,安装包运行时可能触发 SmartScreen | + +--- + +## 二、Tauri Updater 自签名(已启用) + +### 2.1 作用 +- 对自动更新包(`.nsis.zip` / `.msi.zip`)进行数字签名 +- 客户端下载更新后,通过 `tauri.conf.json` 中的公钥验证更新包未被篡改 +- **这是免费的,且与 Windows 操作系统信任无关** + +### 2.2 密钥管理 + +**公钥** +- 文件: `src-tauri/tauri.key.pub` +- 已嵌入 `tauri.conf.json` → `plugins.updater.pubkey` +- **已提交到 Git 仓库**(公钥可以公开) + +**私钥** +- 文件: `tauri.key`(**已删除,未提交到 Git**) +- 必须保存在安全位置(如 GitLab CI/CD Variables、1Password、公司密码管理器) +- **切勿泄露或提交到仓库** + +### 2.3 GitLab CI 配置 + +在 GitLab 项目设置 → **CI/CD → Variables** 中添加: + +| 变量名 | 类型 | 值 | 保护级别 | +|--------|------|-----|----------| +| `TAURI_SIGNING_PRIVATE_KEY` | Variable | `dW50cnVzdGVk...`(私钥 base64 字符串)| Masked + Protected | + +> CI 构建时会自动读取该变量,对更新包进行签名。 + +### 2.4 私钥丢失后的恢复 + +若私钥丢失,必须重新生成密钥对: + +```bash +cd tauri-app +npm run tauri signer generate -- --write-keys src-tauri/tauri.key +``` + +然后: +1. 将新生成的公钥(`tauri.key.pub` 内容)更新到 `tauri.conf.json` +2. 将新生成的私钥保存到 GitLab CI/CD Variables +3. **旧版本客户端将无法通过自动更新升级**(公钥不匹配),必须重新下载安装包 + +--- + +## 三、Windows 安装包签名(待购买证书后启用) + +### 3.1 为什么要商业签名 + +没有签名的 `.exe` 安装包在 Windows 上运行时: +- Microsoft Defender SmartScreen 会显示 **"此应用可能会威胁你的设备安全"** +- 用户必须点击 **"仍要运行"** 才能继续安装 +- 影响品牌信任度和转化率 + +### 3.2 证书类型选择 + +| 类型 | 价格(参考) | SmartScreen 效果 | 推荐度 | +|------|-------------|------------------|--------| +| 标准代码签名证书 (OV) | ¥1,500-3,000/年 | 初次下载仍可能触发,随下载量积累信誉后消除 | ⭐⭐⭐ | +| 扩展验证代码签名证书 (EV) | ¥3,000-6,000/年 | 立即消除 SmartScreen | ⭐⭐⭐⭐⭐ | +| 自签名证书 | 免费 | 需用户手动信任根证书,不适合分发 | ❌ | + +**推荐**: 预算充足时直接购买 **EV 代码签名证书**(如 DigiCert、Sectigo、GlobalSign)。 + +### 3.3 启用商业签名的步骤 + +#### 步骤 1: 购买并获取证书 +从正规 CA 购买 Windows 代码签名证书,获取 `.pfx` 或 `.p12` 文件。 + +#### 步骤 2: 配置 GitLab CI Variables + +在 GitLab 项目设置 → **CI/CD → Variables** 中添加: + +| 变量名 | 类型 | 值 | 说明 | +|--------|------|-----|------| +| `WINDOWS_CERTIFICATE` | Variable | 证书文件的 **base64 编码内容** | `certutil -encode certificate.pfx cert.b64` 生成 | +| `WINDOWS_CERTIFICATE_PASSWORD` | Variable | 证书密码 | Masked | + +> 注意:Tauri CLI 会自动读取这两个环境变量并对 NSIS/MSI 安装包进行签名。 + +#### 步骤 3: 验证签名 + +构建完成后,在 Windows 上右键安装包 → **属性 → 数字签名**,应能看到签名者信息。 + +--- + +## 四、常见问题 + +### Q1: 现在没有商业证书,用户能用吗? +**可以。** 安装包功能完全正常,只是首次运行时会遇到 SmartScreen 提示。可在官网/下载页添加说明,指导用户点击"更多信息"→"仍要运行"。 + +### Q2: Updater 自签名和 Windows 商业签名有什么区别? +| | Updater 自签名 | Windows 商业签名 | +|--|----------------|------------------| +| 成本 | 免费 | 付费 | +| 作用 | 验证更新包完整性 | 验证软件发布者身份 | +| 影响范围 | Tauri 自动更新流程 | Windows 系统级信任 / SmartScreen | +| 是否必须 | 是(否则更新无法验证) | 否(但强烈推荐) | + +### Q3: 可以先用自签名证书绕过 SmartScreen 吗? +**不建议。** 自签名证书需要每个用户手动在系统信任存储中安装根证书,操作复杂且极不专业,仅适用于内部测试。 + +--- + +## 五、相关文件 + +- `src-tauri/tauri.conf.json` — updater 公钥配置 +- `src-tauri/tauri.key.pub` — minisign 公钥(已提交) +- `.gitlab-ci.yml` — CI 构建流程与签名环境变量 diff --git a/tauri-app/src-tauri/tauri.key.pub b/tauri-app/src-tauri/tauri.key.pub new file mode 100644 index 0000000..9526389 --- /dev/null +++ b/tauri-app/src-tauri/tauri.key.pub @@ -0,0 +1 @@ +dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEZCMUQyRjU1MzY3ODZDREIKUldUYmJIZzJWUzhkK3l4VTl0RGE3OFRhN2JXdjBjZnR5UC9aMmwxTUY5K2ZoeDVNOStjZlFwQWYK \ No newline at end of file