r2
Free open-source Cloudflare R2 desktop client and S3 GUI for macOS, Windows, and Linux. Manage Cloudflare R2, AWS S3, M…
家长可控的自建儿童视频流媒体播放器:无广告、无推荐流、封闭内容花园 · Self-hosted, ad-free kids video streaming player with parental controls — Cloudflar…
git clone https://github.com/bitoceango/civideo.gitbitoceango/civideo一套家庭自用的私有儿童视频流媒体:家长把视频上传到 Cloudflare R2,孩子在原生 App(iPhone / iPad / Mac / Windows / Android)里看视频 + 听书。家长可在桌面端(Windows/macOS)开发者模式里自助上传本地视频或从网址(YouTube/Bilibili)下载入库。
English — child-video is a self-hosted, ad-free kids' video + audiobook streaming player with parental controls. Parents upload to their own Cloudflare R2; kids watch in a closed player — no recommendations, ads, comments, or external links. Native apps for iOS / iPadOS / macOS (SwiftUI) and Windows / Android (Tauri); serverless backend on Cloudflare Workers + R2 + D1. Runs at roughly $0 on the free tier.
为什么自己建:商业视频平台充斥推荐流、广告和不适合孩子的内容,孩子很容易被无关视频吸引、无法专注。这个项目是一个封闭内容花园——孩子端没有外部搜索、没有外部入口、没有推荐算法、没有弹幕/社交,只能看到家长放进去的内容。
月成本只有 R2 存储费(起步在免费额度内 = $0,约 500GB ≈ $7/月),出口流量永久免费,无任何年费(孩子端用 SideStore 免费侧载,不交 Apple Developer $99/年)。
家长下载视频 ──cpv 上传──▶ Cloudflare R2 (私有桶)
│ manifest.json = 播放列表单一事实源
▼
Cloudflare Worker (鉴权流媒体网关 + 边缘缓存 + D1 进度/规则)
│ 绑定自有域名(绕开被墙的 *.workers.dev)
┌───────────────┼───────────────┐
▼ ▼ ▼
SwiftUI App Tauri App Tauri App
(iPhone/iPad/Mac) (Windows) (Android)
AVPlayer WebView2 WebView
└────── 共用:首页/分类/听书/我的 + 商业级播放器 ──────┘
家长桌面端(Windows/macOS)开发者模式:捆绑 yt-dlp+ffmpeg,本地处理 →
预签名直传 R2 → 写 manifest(密钥只在 Worker,App 内不存)。听书:cpv 调
豆包 seed-tts-2.0 把电子书转成音频,同一套 R2/Worker/App 链路。
两套前端代码:Apple 端 SwiftUI(
app/);Windows + Android 共用一套 Web UI(windows/src,Tauri v2 分别出安装包/APK)。功能"三端同时实现"为硬性规则(见CLAUDE.md)。
cpv 用 ffprobe 探测,只在必要时重封装/转码。完整设计见 docs/architecture.md。
预编译安装包见 Releases(你需先自部署后端,首次启动填自己的 Worker 地址 + 激活密钥):
| 平台 | 产物 | 安装 |
|---|---|---|
| Windows | childvideo-windows-x64-setup.exe |
双击装。未签名 → SmartScreen 点「更多信息 → 仍要运行」 |
| macOS | 儿童视频_*_aarch64.dmg |
拖入 Applications。未签名/未公证 → 右键「打开」或 xattr -dr com.apple.quarantine |
| Android | app-universal-debug.apk |
手机开「允许安装未知来源」后装(debug 通用包,体积偏大) |
| iOS | *-unsigned.ipa |
⚠️ 不能直接装,需 SideStore/AltStore 自签侧载 |
Windows/macOS 含家长上传(开发者模式);Android 为纯消费端(看视频+听书)。
孩子端 App(三大模块)
播放器(对齐商业流媒体)
家长端(桌面 Windows/macOS,开发者模式·家长 PIN 门后)
有意不做(违背封闭专注理念):算法推荐流、弹幕、评论/社交、热度榜、外链、电商/会员、孩子端 UGC 上传。
| 目录 | 内容 |
|---|---|
cli/ |
上传 CLI cpv(Node + S3 SDK):探测/转码/上传 R2/维护 manifest。专为 AI 调用设计。含 import-youtube.sh 一键导入 |
worker/ |
Cloudflare Worker:激活、媒体网关(Range + 边缘缓存)、进度、家长规则 + D1 schema |
app/ |
SwiftUI 多平台 App(iOS 17+ / macOS 14+,xcodegen 工程),含图标生成脚本 |
windows/ |
Tauri v2 桌面 App(Windows + macOS 共用):src/ 是 Web UI(首页/分类/听书/我的+播放器+家长上传),src-tauri/ 是 Rust 壳;CI 出 NSIS 安装包 / macOS .dmg |
android/ |
Tauri v2 Android 工程:复用 windows/src 的 Web UI,CI 出 APK(消费端:视频+听书) |
tests/ |
e2e-backend.sh 端到端后端验收测试(curl 断言,带退出码) |
docs/ |
架构设计 + requirements/(需求文档:PRD/Epic/Story、验收与测试计划) |
designs/ |
孩子端 UI 设计原型(可在浏览器打开的 HTML) |
任何新需求/功能/改动,必须先有需求文档(docs/requirements/,含 Epic 与 Story)→ 按 Story 建 GitHub issue → 再开发 → 提交关联 issue。详见 CONTRIBUTING.md。没有需求文档和 issue,不写代码。
私密部署参数(域名 / Account ID / 数据库 ID 等)放在
deploy.local.json(已 gitignore,不进仓库)。下面用占位符。
npm run setup 和 CI 能自动建桶/建库/迁移/部署,但下面这些必须你手动完成:
| 步骤 | 说明 |
|---|---|
| 注册 Cloudflare 账号 | 免费:dash.cloudflare.com |
npx wrangler login |
浏览器授权 wrangler(首次部署前必需) |
| 建 R2 API Token(给 CLI 上传用) | 控制台 → R2 → Manage R2 API Tokens → 建 S3 凭证,填进 ~/.zshrc 环境变量(见 cli/README.md)。⚠️ wrangler 部署不需要它,但 CLI 上传视频需要 |
| (可选)自定义域名 | 把域名托管到 Cloudflare;不绑就用免费 *.workers.dev(中国大陆可能被墙) |
| iOS 设备分发 | 见 §3:免费 Apple ID 自建(证书 7 天)或 SideStore 自动续签侧载 |
| (可选)开启 CI 自动部署 | 仓库 Settings → Actions 配 Secret CLOUDFLARE_API_TOKEN + Variables CF_ACCOUNT_ID/D1_DATABASE_ID/CF_DOMAIN,之后合并到 main 自动部署 worker |
先 npx wrangler login(浏览器登录,首次必需)。然后一键部署(推荐)——自动建 R2 桶 / 建 D1 并写回 id / 迁移表 / 设密钥 / 部署,只问你域名和密钥:
cd worker npm install npm run setup # 默认免费 *.workers.dev(零域名);过程中可选绑定自定义域名
💡
*.workers.dev在中国大陆可能被墙;需要稳定访问时按提示绑定自定义域名(需已托管在 Cloudflare)。
cd worker npm install cp wrangler.example.jsonc wrangler.jsonc # 默认 workers.dev;要自定义域名改这里 npx wrangler r2 bucket create child-video # 建 R2 桶 npx wrangler d1 create child-video-db # 建 D1,把返回的 database_id 填进 wrangler.jsonc npx wrangler d1 execute child-video-db --remote --file=./schema.sql npx wrangler secret put ACTIVATION_KEY # 设备激活密钥:长随机串(openssl rand -hex 24);不设则回退用 PARENT_PIN npx wrangler secret put PARENT_PIN # 家长门 PIN:改每日时长/允许时段规则用,可短数字 npx wrangler deploy
后端有两个完全由你自定义的密钥(互相独立,issue #17 起分离):
| 密钥 | 是什么 | 在哪用 | 怎么设 |
|---|---|---|---|
设备激活密钥 ACTIVATION_KEY |
一台设备首次"加入"你家库的口令 | App 激活页(家长把它给家人,在 Windows/Android/Mac/iOS 上激活设备时输入一次) | npm run setup 时回车=随机生成,或自己输任意值;改用 wrangler secret put ACTIVATION_KEY。建议长随机串 openssl rand -hex 24 |
家长门 PARENT_PIN |
进 App 内「家长中心」的 PIN | 改每日时长/允许时段规则、桌面端家长上传时输入 | npm run setup 时你输入,可短数字(如 1234);改用 wrangler secret put PARENT_PIN |
二者分工:激活密钥管"哪台设备能连你的库";家长 PIN管"谁能改规则/上传"。
setup结束会打印激活密钥,妥善保存。若不设ACTIVATION_KEY,激活会回退用PARENT_PIN(不推荐,二者最好分开)。
cd cli && npm install # 配置 R2 S3 凭证(见 cli/README.md),然后: node src/index.js doctor --json # 自检 ffmpeg + R2 连通性 node src/index.js upload video.mp4 --title "标题" --series "系列名" --category "科学" --json
需要本机 ffmpeg(brew install ffmpeg)。
从 YouTube / Bilibili 等导入视频,三种方式任选:
brew install yt-dlp ffmpeg bash cli/import-youtube.sh "<播放列表URL>" "动物兄弟 第五季" "科学" # 720p+中文字幕 → 逐个上传
import-youtube.sh已内置env -u NODE_OPTIONS+--extractor-args player_client=...绕过常见拦截;带--cookies-from-browser可下需登录内容。
最省事:下预编译包 → Releases(Windows .exe / macOS .dmg / Android .apk / iOS .ipa)。首次启动在激活页填你的 Worker 域名 + 设备激活密钥。
从源码构建:
Apple(iOS / macOS,SwiftUI · app/)
cd app && brew install xcodegen cp Local.example.xcconfig Local.xcconfig # 可填 CV_SERVER_HOST=你的主机名,免每次手输 xcodegen generate && open ChildVideo.xcodeproj
Mac 直接 Run;iPhone/iPad 见 app/README.md(免费 Apple ID + SideStore)。
Windows / macOS(Tauri · windows/,含家长上传)
cd windows npx @tauri-apps/cli@2 build # 本机出 .exe(Win) / .app+.dmg(Mac);或 `dev` 开发模式跑
桌面端进「我的 → 家长中心」(家长 PIN)后有 📤 上传视频:本地文件(单个/多选/整文件夹)+ ⬇ 网址下载(YouTube/Bilibili)。需把 yt-dlp/ffmpeg 按 target-triple 命名放进 windows/src-tauri/binaries/(CI 自动拉;本地手动放,见各 CI 步骤)。
Android(Tauri · android/,纯消费端)
复用 windows/src 的 Web UI,由 CI 出 arm64 APK(.github/workflows/android-build.yml),见 Release。
所有端共用同一后端;首次启动填 Worker 域名 + 设备激活密钥即可(个人 Apple 构建可用
Local.xcconfig预填)。
source ~/.zshrc PIN=<你的PIN> bash tests/e2e-backend.sh # 端到端后端验收,退出码 0=全过
覆盖:健康检查 / 鉴权 401 / PIN 403 / 激活 / 拉库 / 媒体 Range 206 / 边缘缓存 HIT / 进度读写 / 家长规则 / 超时段·超时长拦截 / 本周报告。验收清单见 docs/requirements/002-acceptance-e2e.md。
deploy.local.json)。/api/activate 内置限流——同一 IP 连续失败 5 次即锁定 15 分钟(返回 429),计数持久化在 D1;可用环境变量 MAX_ACTIVATION_FAILS / ACTIVATION_LOCK_MIN 调整。⚠️ 自定义域名会进公开的 Certificate Transparency 日志(域名不是秘密),安全只靠 PIN 强度 + 限流,请设强 PIN。(升级老部署需重跑 schema.sql 以建 activation_attempts 表。)http.request.uri.path eq "/api/activate" 设「每 IP 每分钟 ≤ 5 次,超出 Block」。more like this
Free open-source Cloudflare R2 desktop client and S3 GUI for macOS, Windows, and Linux. Manage Cloudflare R2, AWS S3, M…
L5 is a fun, fast, cross-platform, and lightweight implementation of the Processing API in Lua.
Educational ARES is a version of ARES OS 2.0 modified for classroom use with a Prusa MK4S 3D printer and a USB camera.…
search projects, people, and tags