跳到主要内容
AI教程

使用 ShrimpReel 构建并发布 AI 爆款视频 SaaS

了解如何在本地运行 ShrimpReel,将其定制为适合爆款视频趋势的应用,配置支付和视频生成、创建 Cloudflare 资源、确保安全部署,并让每个关键词专属网站与上游模板保持同步。

使用 ShrimpReel 构建并发布 AI 爆款视频 SaaS

ShrimpReel 是什么?

ShrimpReel 是一个开源 SaaS 模板,用于构建将一张上传的照片转换为基于病毒式传播格式的 AI 生成视频的网站。预期工作流程是:为每个热门关键词创建单独的代码仓库,修改网站配置和双语内容,替换媒体资源,然后将完成的应用部署到 Cloudflare。

该技术栈结合了 TanStack Start、React 19 和 Tailwind CSS 4,用于前端和服务端渲染。Hono API 负责处理 /api/* 下的路由、媒体传输、robots 指令、站点地图和 IndexNow 验证。服务器入口点是 src/server.ts。

该应用围绕 Cloudflare Workers、D1、R2、KV、Queues、Rate Limiting 和 Cron Triggers 设计。英文页面从 / 提供,中文页面位于 /zh 下。

项目状态:根据 README,完整工作流程已通过本地单元测试和 Playwright 端到端测试,但该模板尚未经过生产部署验证。在依赖各项集成连接真实服务之前,请先查看 ROADMAP.md。

主要功能

账户、账单和积分

  • 支持 Google 登录,包括 Google One Tap,以及仅限 localhost 的开发登录。
  • 积分包,以及可选的月度或年度订阅。
  • 积分账本、兑换码、推荐链接、账单历史、可打印的订单详情、账户删除和数据导出。
  • 默认支付服务商 Waffo Pancake,或可选用 Dodo Payments。
  • 支持部分和全额退款,并自动扣回相应积分。

视频生成

  • 默认使用 fal.ai 队列 API 作为视频服务商。
  • 支持可选地通过 yir.ai 路由请求。
  • 本地开发和测试期间,模拟服务商会复制模板视频。
  • 生成队列、死信队列,以及生成失败时自动退还积分。
  • 用户可以按视频启用公开视频分享页面。

增长、管理和运营

  • 使用 UTM 值和广告点击标识符进行首次触点和末次触点归因。
  • 访问到生成的转化漏斗,以及受同意控制的 GA4 事件。
  • 提供用户、订单、生成记录、支付事件、下架处理、举报、邮件、审计记录、推荐、运行时设置和连接测试的管理界面。
  • 服务商成本和毛利率报告。
  • 维护模式、公告、每日生成限制、健康警报、浏览器错误报告和支付通知。
  • 每日将 D1 备份到 R2。

安全、数据保留和 SEO

  • 上传内容审核,以及视频上的 AI 生成标签。
  • 七天后自动删除照片,30 天后自动删除视频。
  • 48 小时下架队列:移除由同一源照片制作的视频,并屏蔽该照片。
  • 联系表单和举报表单支持 Turnstile。
  • 规范 URL、hreflang 元数据、JSON-LD、站点地图、法律页面、指南、相关文章和代码分割的本地化文案。
  • 可通过 npm run seo:check 使用全站 SEO 检查器。

前置要求

安装 Node.js 和 npm 11.19 或更高版本。较旧的 npm 版本可能会以某种形式重写 package-lock.json,之后导致持续集成中的 npm ci 失败。

要进行生产部署,还需要 Cloudflare 账户、支付服务商账户、视频服务商 API 密钥和 Google OAuth 凭据。只有使用随附脚本重新生成占位媒体时才需要 FFmpeg。

在本地安装并运行 ShrimpReel

1. 安装依赖并创建本地变量

npm install
cp .dev.vars.example .dev.vars

打开 .dev.vars,至少设置 SESSION_SECRET。生产环境和预发布环境要求使用至少 32 个字符的强值。README 建议使用以下命令生成:

openssl rand -hex 32

2. 准备本地数据库和媒体存储

npm run seed:local

此命令会应用 D1 迁移,并将 seed/templates/*.mp4 中的文件上传到本地模拟的 R2 存储。

3. 启动开发服务器

npm run dev -- --host 127.0.0.1

打开 http://127.0.0.1:3000。在 Windows 上明确使用 127.0.0.1 还可以避免测试工具将 localhost 解析为 IPv6 时出现问题。

不要在 0.0.0.0 上运行开发服务器,也不要直接将其暴露到互联网。开发登录、模拟支付和 /api/dev/* 仅用于直接的 localhost 请求。

尝试基本工作流程

默认本地配置使用 PAYMENT_PROVIDER=mock、VIDEO_PROVIDER=mock 和 MODERATION_PROVIDER=mock。这样可以在不扣款或向外部视频服务提交任务的情况下体验产品。

  1. 打开登录页面,并使用生产环境之外显示的开发登录方式。
  2. 选择积分包。模拟结账会模拟支付,但不会产生任何扣款。
  3. 上传照片并开始生成。
  4. 模拟视频服务商会复制预置的模板视频,而不是调用 AI 模型。
  5. 打开控制面板,查看生成的视频、积分账本、账单记录和分享设置。

要模拟上传被拒绝,请在上传表单中提交 mockOutcome=reject。如果希望在本地禁用 Turnstile,请将 TURNSTILE_SITE_KEY 留空。

你还可以测试当前已登录用户媒体的保留清理功能:

POST /api/dev/sweep
Content-Type: application/json

{"days": 8}

本地邮件投递为模拟操作。使用以下命令查看发件箱:

GET /api/dev/emails?to=user@example.com&ref=<order-or-takedown-id>

为新趋势创建网站

1. 克隆仓库,同时保留上游历史记录

git clone https://github.com/qianshuixia/shrimpreel.git moonhop
cd moonhop
git remote rename origin upstream
git remote add origin git@github.com:<owner>/moonhop.git

如果希望合并未来的模板更新,请不要使用 GitHub 的模板按钮。通过这种方式创建的仓库与源仓库没有共享历史记录。使用带有 upstream 远程仓库的普通克隆可以保留合并基点。

2. 运行网站脚手架

先执行试运行,检查拟进行的更改,然后添加 --write:

node scripts/new-site.mjs --keyword "Moon Hop" --domain moonhop.ai --keywords "AI dance video,Moon Hop filter"
node scripts/new-site.mjs --keyword "Moon Hop" --domain moonhop.ai --keywords "AI dance video,Moon Hop filter" --write

脚手架会更新 site.ts、wrangler.jsonc 中的 Cloudflare 资源名称以及软件包名称。它会重置部署专用标识符,并移除模板的暂存环境配置。随后,它会输出剩余手动操作的检查清单。

3. 配置定价和生成设置

编辑 src/config/site.ts。检查 packages 中的积分包、subscriptionsEnabled 开关、订阅 plans、可用的 durations 以及 video.falModel。

如果网站只应销售一次性积分包,请将 subscriptionsEnabled 设置为 false。积分包可以使用 anchorPriceCents 显示划线的对比价格,但 README 警告,该价格应当确实是该积分包曾经实际销售时的价格。新网站通常不设置此字段。

4. 重写本地化内容

替换 src/content/en.ts 和 src/content/zh.ts 中与趋势相关的文案。至少要重写主视觉区、说明、创意、常见问题以及两篇内置文章。可选的问题和对比模块也应重写或设置为 null。

避免只在现有文本中机械地替换关键词。模板明确提醒,机械复制的网站可能会被搜索引擎视为规模化内容滥用。

要添加文章,请先在 site.ts 的 articles 部分创建其元数据条目,然后为每种语言环境添加匹配的内容键。文章会自动加入指南中心、网站地图以及已配置的相关文章链接。请保留现有的 trend 和 howTo 条目,因为首页会链接到它们。

5. 替换所有占位媒体

  • 将源生成视频片段放入 seed/templates/,并使用 <template.id>-<seconds>s.mp4 格式。
  • 替换 public/demo/ 中的首页视频和海报图。
  • 替换 public/og.png 和 public/favicon.svg。
  • 仅使用原创或获得许可的演示媒体,并将其署名记录在 site.examples.*.credit 中。

如果系统提供 FFmpeg,可使用以下命令重新生成项目原有的占位媒体:

node scripts/generate-placeholder-media.mjs

更改 template.id 后,请从 seed/templates/ 中删除过时的模板文件。

配置真实服务提供商

运行时变量

在 wrangler.jsonc 中设置非机密的生产环境变量。重要值包括 SITE_URL、APP_ENV=production、PAYMENT_PROVIDER、VIDEO_PROVIDER、MODERATION_PROVIDER、TURNSTILE_SITE_KEY、ADMIN_EMAILS、EMAIL_FROM、产品映射以及 GOOGLE_CLIENT_ID。

支付服务提供商的产品价格具有权威性。网站显示的价格必须与服务提供商控制台保持同步。产品映射会将每个已配置的积分包或计划关联到其服务提供商产品 ID。

密钥

根据所选集成,密钥可能包括 SESSION_SECRET、GOOGLE_CLIENT_SECRET、Waffo 凭据、Dodo 凭据、FAL_KEY、可选的 YIR_API_KEY、用于审核的可选 OPENAI_API_KEY 以及 TURNSTILE_SECRET_KEY。

使用以下命令设置单个密钥:

npx wrangler secret put <NAME>

或者,复制并填写生产环境变量文件,检查执行计划,然后应用缺失的密钥:

cp .dev.vars.example .dev.vars.production
node scripts/sync-secrets.mjs
node scripts/sync-secrets.mjs --apply

同步脚本不会输出密钥值。除非提供 --overwrite,否则现有的远程密钥会被保留。

配置 Cloudflare 资源

为每个关键词网站创建独立的资源集。名称必须与 wrangler.jsonc 中的绑定一致。

npx wrangler d1 create <name>
npx wrangler r2 bucket create <name>-media
npx wrangler kv namespace create <name>-kv
npx wrangler queues create <name>-jobs
npx wrangler queues create <name>-jobs-dlq
npm run db:migrate:remote
npx wrangler r2 object put <name>-media/templates/<file>.mp4 --file seed/templates/<file>.mp4 --content-type video/mp4 --remote

将生成的 D1 数据库 ID 和 KV 命名空间 ID 复制到 wrangler.jsonc 中。每个网站的速率限制 namespace_id 在 Cloudflare 账户内也必须保持唯一。

按照项目中的说明配置 R2 生命周期规则,使上传的照片和生成的视频分别遵循七天和 30 天的保留期限。在事务性电子邮件正常工作之前,还必须先通过 Cloudflare Email Service 完成发送域名的接入。

验证并部署

运行本地质量检查

npm run typecheck
npm test
npm run test:e2e
npm run seo:check

部署前,运行配置诊断工具:

npm run doctor

该工具会检查环境、域名、所选提供商、产品映射、Cloudflare 资源绑定、队列、Cron 配置、必需的密钥名称、尚未应用的迁移,以及未解决的 TODO(site) 标记。当远程检查暂时不可用时,使用 --offline。

部署并运行冒烟测试

npm run deploy
SMOKE_BASE_URL=https://<domain> npm run test:smoke

npm run deploy 会先运行部署前检查。部署后,在 Cloudflare 中绑定自定义域名,并确保 SITE_URL 与 site.domain 完全一致。规范 URL、站点地图以及同源 CSRF 检查都依赖这一匹配关系。

自定义域名正常工作后,将 workers_dev 和 preview_urls 设置为 false。否则,生产 Worker 仍可通过公开的 Cloudflare 开发和版本 URL 访问,并使用相同的 D1 和 R2 资源。

完成 SEO 上线任务

npm run seo:check -- --base https://<domain> --production
npm run seo:indexnow -- --submit

仅在配置好 site.seo.indexNowKey 后运行 IndexNow 命令。在 Google Search Console 和 Bing Webmaster Tools 中验证域名,然后提交 https://<domain>/sitemap.xml。

高级技巧

确保生产环境不使用模拟实现

如果所选提供商仍设置为 mock,生产环境和预发布环境会对结账、生成和上传请求返回 503 响应并拒绝处理。开发环境登录、模拟结账路由和开发环境 API 端点在这些环境中会返回 404。请将其视为安全机制,而不是运行 npm run doctor 的替代方案。

合并模板更新,而不是复制补丁

将站点专属的工作保留在 src/config/site.ts、src/content/*、public/*、seed/、wrangler.jsonc 以及 package name 中。共享修复应在模板中完成,然后合并到每个站点。

git fetch upstream
git show upstream/main:scripts/sync-plan.mjs > .tmp/sync-plan.mjs
node .tmp/sync-plan.mjs
git merge --no-ff upstream/main
npm install
npm run typecheck
npm test
npm run test:e2e
npm run db:migrate:remote

使用合并提交,不要使用压缩合并、变基或拣选提交。同步计划依赖 git merge-base HEAD upstream/main。记录合并时,将 Template-sync: <template commit sha> 放在提交消息末尾。

在部署期间保持向后兼容

如果迁移运行后部署失败,可以回滚新的 Worker 版本,但 D1 迁移不会自动撤销。请确保迁移与之前的应用版本兼容,以便能够回滚。

适时使用随附的 Claude Code 工作流

仓库包含用于搭建趋势主题站点的 new-hot-site 技能、用于合并模板变更的 sync-upstream 技能,以及用于上线前和线上检查的只读 launch-audit 技能。这些工具不能替代人工审核:生成的文案、获得授权的媒体资源、域名、提供商产品、OAuth 设置、电子邮件接入和生命周期策略仍需核验。

修改核心逻辑前先查阅项目文档

修改积分、支付履约、双语内容、迁移或端到端测试之前,请查阅 AGENTS.md。更多详情请参阅 docs/env.md、docs/payments.md、docs/subscriptions.md、docs/SEO_AUDIT.md 和 docs/SAAS_VIDEO_FEATURES.md。README 说明这些文档目前使用中文编写。

结语

ShrimpReel 为以关键词为重点的 AI 视频 SaaS 提供了全面的起点,涵盖生成队列、计费、积分、管理、保留策略、合规工作流、分析、SEO 和 Cloudflare 运维。请从安全的模拟工作流开始,定制所有站点专属层,将占位内容替换为获得授权的资源,核验所有提供商和 Cloudflare 设置,并仅在完整的测试、诊断、SEO 和冒烟测试流程全部通过后部署。