Skip to content

About

Tool that removes youtube clickbait

Resources

Stars

7 stars

Watchers

0 watching

Forks

Repository files navigation

Face Value logo

Face Value

Take YouTube at face value.
A browser extension that rewrites clickbait titles from the video's actual transcript, replaces engineered thumbnails with a real frame from the video, and removes Shorts entirely.

facethevalue.com · privacy · support the project


Every thumbnail on YouTube is a bid for your attention, and the bids keep escalating. Shocked faces, red arrows, capital letters, promises the video never keeps. Even honest creators package good work this way, because the algorithm rewards whoever grabs hardest. And when packaging individual videos isn't enough, there's Shorts: an infinite scroll engineered for the dopamine hit itself, built to keep you swiping instead of watching anything you actually chose.

Face Value takes those levers away. Titles say plainly what a video is, thumbnails are just a frame from the video, and Shorts disappears from the site entirely. What's left is a feed you choose from, not one that plays you.

  • Clean titles. Rewritten from the video's transcript to say what it actually delivers. Hover any cleaned title to see the original.
  • Clean thumbnails. A real frame extracted from the video itself.
  • Hide Shorts. One toggle removes Shorts shelves, reels, and the sidebar button.
  • Channel exceptions. Pause Face Value on channels you trust.
  • No account, no analytics. The only thing sent off your device is the public video ids and titles on pages you view. Full details in the privacy policy.

Live streams and search results are intentionally left untouched: searching is deliberate navigation, and the feed is where the algorithm steers.

How it works

The extension only ever does one cheap batched read; all expensive work happens asynchronously behind a shared cache, so the whole system gets faster as more people use it. The serverless layer (API, cache, queues, CDN) is AWS; the two things that need a clean, non-datacenter IP to talk to YouTube (captions and video bytes) run on a flat-cost VPS behind a VPN and a fixed-fee ISP proxy pool.

flowchart LR
    subgraph Browser
        EXT[Content script]
    end
    subgraph AWS
        API[API Gateway] --> RES[Resolver λ]
        RES <--> DDB[(DynamoDB cache)]
        RES -- miss --> Q1[[SQS titles]]
        Q1 --> TW[Title worker λ<br/>oEmbed · gates · LLM rewrite]
        TW --> DDB
        TW -- passed gates --> Q2[[SQS thumbnails]]
        S3[(S3 frames)] --> CF[CloudFront]
        Q2 -. disabled fallback .-> THL[Thumb worker λ<br/>+ residential proxy]
        ALM[CloudWatch alarms] --> SNS[SNS → email]
    end
    subgraph VPS["VPS (Hetzner) behind Mullvad + ISP proxy pool"]
        CAP[Caption service<br/>yt-dlp android/ios · json3]
        THP[Pooled thumb worker<br/>16 threads · yt-dlp web_embedded + deno · ffmpeg frame vote]
        POOL[(Exit pools<br/>ISP IPs · Mullvad relays)]
        CAP --- POOL
        THP --- POOL
    end
    EXT -- "POST /titles (batch)" --> API
    TW -- "GET /captions" --> CAP
    TW --> LLM[qwen-flash → Gemini Flash-Lite]
    Q2 --> THP
    THP --> S3
    THP --> DDB
    EXT -- overlay img --> CF
    POOL -. player + stream bytes .-> YT[(YouTube)]
Loading

Titles. The worker verifies the video via YouTube's public oEmbed API, asks the VPS caption service for the transcript (YouTube's own auto-captions, fetched through a clean exit), applies the demand gates (under a minute or under 10k views is left alone), and has a small LLM (qwen-flash, Gemini Flash-Lite as fallback) rewrite the title to state what the video actually contains. Grounding the rewrite in the transcript is the whole trick. If the caption lane is unhealthy the cure fails and retries rather than caching a title-only guess; a video that genuinely has no captions is rewritten from the title alone and marked as such.

Thumbnails. One pooled worker process runs sixteen jobs at a time: the yt-dlp web_embedded client (with deno solving YouTube's JS challenge) exposes a direct stream URL, the worker fetches only the first ~0.2 MB by Range request, and ffmpeg scores every decodable frame on sharpness, entropy, and luminance in one pass and keeps the best real frame. 720p output from a fifth of a megabyte, independent of video length. An ffmpeg semaphore keeps the CPU part bounded; the network waits overlap. Each job picks an exit from a pool of Mullvad relays and retries once through the ISP pool if YouTube refuses the VPN exit.

Client. The content script masks cards with a CSS gate injected at document_start, so the clickbait version is never painted. Results overlay YouTube's own elements, and uncached videos resolve in a few seconds via bounded polling. Every card has a hard deadline, so the page never hangs on our backend.

Operations. Prepaid, hard-capped LLM accounts; an AWS budget with a deny-all freeze action; CloudWatch alarms on queue age, thumb completions, and the share of cures that came back without a transcript, all to one SNS email.

Repo layout

extensions/            MV3 extension (chrome / edge / firefox, built from shared/)
src/resolver/          API Lambda: batch cache lookup + queueing (TypeScript)
src/worker/            Title worker: oEmbed + captions + gates + LLM rewrite (TypeScript)
src/thumbnail-worker/  Frame extraction pipeline: yt-dlp + ffmpeg (Python). Shared by the
                       VPS worker and the (disabled) Lambda container image
vps/                   Everything that runs on the box: caption service, pooled thumb
                       worker, exit pools, health check, systemd units, README
template.yaml          AWS SAM stack (API, queues, table, CDN, Lambdas, budget)
tools/                 Local harnesses (LLM head-to-head, proxy cost, frame-vote A/B)
localworker/           Home-IP DLQ drainer (launchd)

Running your own

The backend is one SAM stack plus one small Linux box. You need an AWS account, Docker (for the container Lambda), and SSM SecureString parameters for the LLM keys and the caption-service token; the header of template.yaml documents them.

sam build && sam deploy --guided

The box needs WireGuard to a VPN with per-relay SOCKS exits (Mullvad works), a list of fixed-fee ISP proxies, yt-dlp with yt-dlp-ejs and deno, and ffmpeg; vps/README.md walks through the units and the exit pools. Point API_BASE in extensions/shared/content.js at your endpoint, run extensions/build.sh, and load the browser folder of your choice as an unpacked extension.

License

MIT. Fonts (Hanken Grotesk, Newsreader, JetBrains Mono) are bundled under the SIL Open Font License. yt-dlp and ffmpeg are used server side under their respective licenses.

About

Tool that removes youtube clickbait

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages