Skip to content
<Hyun/>
All projects

Church Website & Member Platform

Personal · Community tools

Publish 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 / 6
Explore the architectureSystem diagrams, design decisions and detailed flows

Church site architecture

  1. Members & adminssigned-in browser
    Step 1, edits
    CLOUDFLARE WORKERAstro server routes/members, /manage, /auth
    Step 2, commit
    GITHUBGitHub repoMarkdown + JSON content
    push / commit, both ways
    GITHUBGitHub Actionsbuild, deploy, sync
    Step 3, build + deploy
    CLOUDFLARE WORKERStatic pagesprerendered Astro

Other connections

  • Public visitorstoStatic pages
  • Astro server routestoCloudflare D1SQL binding
  • Astro server routestoGoogle / Facebook
  • GitHub ActionstoYouTube feedweekly RSS
One Cloudflare Worker serves the static Astro pages and the members-only server routes on D1. The purple path is an admin's content edit: (1) the edit in the browser editor, (2) the validated commit to GitHub, (3) the GitHub Actions build and redeploy.
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

  1. USER'S COMPUTERBrowser dashboardserved on 127.0.0.1
    USER'S COMPUTERserver.pylocal API + jobs
    probe, cut
    USER'S COMPUTERFFmpeg / ffprobelocal subprocess
  2. server.py
    windows
    USER'S COMPUTERAST classifierONNX Runtime on CPU
  3. server.py
    ordered upload
    GOOGLEYouTube Data APIresumable upload

Other connections

  • server.pytoApp data folder
  • AST classifiertoHugging Face Hubcached
  • server.pytoGoogle OAuthtoken refresh
  • server.pytoDownload siteself-update
A loopback-only Python server on the user's computer drives FFmpeg and an ONNX audio classifier and keeps all work in a local app-data folder. The purple path runs from the dashboard to a YouTube upload; the app goes online only for the model download, Google sign-in, YouTube uploads and self-updates.
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

  1. Service recordinglocal copy
    first 30 min
    FFmpeg audio pull16 kHz mono
    PCM samples
    AST on ONNX10 s window every 5 s
    per-window scores
    scores.jsonmusic / singing / speech
    windows
    Segmenterthreshold, bridge ≤45 s
    segment 1
    FFmpeg cutstream copy or re-encode
    faststart MP4
    output.mp4reviewed before upload
How a recording becomes candidate worship sections and an edited MP4. In quick mode the scan starts with the first 30 minutes and grows 10 minutes at a time, scoring only the new audio.
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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

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