Church Website & Member Platform
Personal · Community toolsPublish the site. Support the community.
Edit the site, manage members, or turn a service recording into a reviewed praise video queued for YouTube.
Interactive explanation · not the live service
Loading interactive explanation…
Watch the original recordingsPraise Studio · Church site · Recording notes included
Use the left and right arrow keys to switch slides.
Recorded from a local run on a synthetic test recording; analysis and rendering are fast-forwarded where labeled. This recording ends at MP4 creation. The interactive Praise Studio above continues through review and a simulated YouTube upload.
Choosing a synthetic test recording, analyzing it (fast-forwarded), reviewing the two detected song sections and rendering section 1 to MP4.
1 / 6Explore the architectureSystem diagrams, design decisions and detailed flows
Church site architecture
- Members & adminssigned-in browserStep 1, editsCLOUDFLARE WORKERAstro server routes/members, /manage, /authStep 2, commitGITHUBGitHub repoMarkdown + JSON contentpush / commit, both waysGITHUBGitHub Actionsbuild, deploy, syncStep 3, build + deployCLOUDFLARE WORKERStatic pagesprerendered Astro
Other connections
- Public visitorstoStatic pages
- Astro server routestoCloudflare D1SQL binding
- Astro server routestoGoogle / Facebook
- GitHub ActionstoYouTube feedweekly RSS
View the diagram as text
Parts
- Public visitors (browser): Client / UI
- Members & admins (signed-in browser): Client / UI
- Static pages (prerendered Astro): Hosting / CI
- Astro server routes (/members, /manage, /auth): Owned service
- Cloudflare D1 (users, sessions, reports): Data store / broker
- YouTube feed (channel RSS): External service
- GitHub Actions (build, deploy, sync): Background job
- GitHub repo (Markdown + JSON content): Data store / broker
- Google / Facebook (OAuth sign-in): External service
Connections
- Step 1: Members & admins → Astro server routes: edits
- Step 2: Astro server routes → GitHub repo: commit
- GitHub repo ↔ GitHub Actions: push / commit
- Step 3: GitHub Actions → Static pages: build + deploy
- Public visitors → Static pages
- Astro server routes → Cloudflare D1: SQL binding
- Astro server routes → Google / Facebook
- GitHub Actions → YouTube feed: weekly RSS
Praise Studio architecture
- USER'S COMPUTERBrowser dashboardserved on 127.0.0.1USER'S COMPUTERserver.pylocal API + jobsprobe, cutUSER'S COMPUTERFFmpeg / ffprobelocal subprocess
- server.pywindowsUSER'S COMPUTERAST classifierONNX Runtime on CPU
- server.pyordered uploadGOOGLEYouTube Data APIresumable upload
Other connections
- server.pytoApp data folder
- AST classifiertoHugging Face Hubcached
- server.pytoGoogle OAuthtoken refresh
- server.pytoDownload siteself-update
View the diagram as text
Parts
- App data folder (jobs, media, scores): Data store / broker
- FFmpeg / ffprobe (local subprocess): External service
- Browser dashboard (served on 127.0.0.1): Client / UI
- server.py (local API + jobs): Owned service
- AST classifier (ONNX Runtime on CPU): Owned service
- Hugging Face Hub (model files, once): External service
- Download site (release zip): Hosting / CI
- Google OAuth (desktop flow + PKCE): External service
- YouTube Data API (resumable upload): External service
Connections
- Browser dashboard → server.py
- server.py → FFmpeg / ffprobe: probe, cut
- server.py → AST classifier: windows
- server.py → YouTube Data API: ordered upload
- server.py → App data folder
- AST classifier → Hugging Face Hub: cached
- server.py → Google OAuth: token refresh
- server.py → Download site: self-update
Praise Studio audio pipeline
- Service recordinglocal copyfirst 30 minFFmpeg audio pull16 kHz monoPCM samplesAST on ONNX10 s window every 5 sper-window scoresscores.jsonmusic / singing / speechwindowsSegmenterthreshold, bridge ≤45 ssegment 1FFmpeg cutstream copy or re-encodefaststart MP4output.mp4reviewed before upload
View the diagram as text
Parts
- Service recording (local copy): Data store / broker
- FFmpeg audio pull (16 kHz mono): External service
- AST on ONNX (10 s window every 5 s): Owned service
- scores.json (music / singing / speech): Data store / broker
- Segmenter (threshold, bridge ≤45 s): Owned service
- FFmpeg cut (stream copy or re-encode): External service
- output.mp4 (reviewed before upload): Data store / broker
Connections
- Service recording → FFmpeg audio pull: first 30 min
- FFmpeg audio pull → AST on ONNX: PCM samples
- AST on ONNX → scores.json: per-window scores
- scores.json → Segmenter: windows
- Segmenter → FFmpeg cut: segment 1
- FFmpeg cut → output.mp4: faststart MP4
How an admin's content edit goes live
Admin signs in
The admin logs in with Google, Facebook or email and password. On every server-rendered request, middleware looks up the session in D1, lets only active admins into /manage and rejects cross-origin form posts.
Open in the browser editor
The editor loads the post's Markdown or the site settings JSON straight from the GitHub repo, along with the file's SHA.
Validate and commit
On save, the Worker validates the values with the same Zod schemas the Astro build uses and rejects the save if the file changed since it was opened. The file and any uploaded photos go into one commit under the editor's name, retried once if main moved in the meantime.
Shown as pending deploy
A change row with the commit SHA is written to D1, so the admin list shows the edit as 'pending deploy' until a newer build is live. Files uploaded with the edit are served from the repo in the meantime.
Actions builds and deploys
The push to main runs the deploy workflow: install, astro build, then wrangler deploy of the static pages and server routes together. Visitors get the rebuilt page a few minutes after the save.
From a recording to a YouTube upload
Import the recording
The dashboard streams the chosen file to the local server, which checks free space, copies it into the app-data folder and uses ffprobe to confirm it has video and audio. Backlog imports are queued by the service date in the file name.
Score the audio
FFmpeg extracts 16 kHz mono audio from the first 30 minutes. The AST model, downloaded once at a pinned revision, scores a 10-second window every 5 seconds for music, singing and speech, and the scores are cached.
Detect the worship section
A window counts as singing when music beats speech by the sensitivity threshold and a voice is present. Nearby singing windows are joined, and the scan widens 10 minutes at a time until it finds a 2-minute section and the singing has stopped.
Cut the MP4
A single H.264/AAC section is stream-copied without re-encoding; multiple sections or incompatible sources switch to an exact re-encode. The original file is never modified.
Review and upload in order
A person previews the edit and sets the title, description, privacy and thumbnail. Reviewed videos upload strictly in the saved order through YouTube resumable uploads, stopping at the first failure or quota limit so a re-run continues from that video.
The project & my contribution
- Problem
- A Korean church in Kansas paid $56 a month for a hosted website.
- Solution
- A rebuilt site with a member area for small-group reports, run on Cloudflare's free plan and edited from the browser with every change committed to GitHub. Praise Studio prepares worship videos.
- Result
- The hosted website was replaced at no hosting cost, and every content edit stays in Git history.
- $0 hosting vs. $56/month
Live site: The interface is in Korean.
How it's built
- Astro on one Cloudflare Worker with D1, so the whole site fits on the free plan
- Google, Facebook or email sign-in; social sign-ups wait for admin approval
- Hashed session tokens, PBKDF2 passwords and same-origin checks on form posts
Highlights
- Git is the CMS: browser edits are validated, committed to GitHub and deployed automatically
- Every edit stays in Git history, while member data stays only in D1
Praise Studio
- Local tool that finds the worship section of a service recording with an ONNX audio model
- Cuts it with FFmpeg and queues reviewed videos for YouTube upload
- Runs on the user's computer; only the final upload leaves the machine