Skip to content

About

Chrome MV3 and PWA prototype for local-scored YouTube live danmaku overlays

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

177 Commits

Folders and files

Repository files navigation

English | 日本語

Smart YouTube Comment Overlay

Chrome Web Store

Chrome MV3 extension for a Nico-style YouTube live chat overlay. It scores messages locally in JavaScript and uses that score to decide whether a comment should move quickly, normally, or slowly across the video.

The goal is to keep useful comments visible without letting short repeated reactions, emoji floods, or low-value bursts bury everything else.

Install

The extension is published on the Chrome Web Store:

https://chromewebstore.google.com/detail/nkphcfhnfjceplpgcjccnpfdkheafohp

The store listing tracks the last version that passed Chrome Web Store review, so it can trail the version in this repository. To run the newest source, load extension/ unpacked as described in Load In Chrome.

Status

Published on the Chrome Web Store. Implemented:

  • Chrome MV3 extension scaffold
  • mobile PWA under web/
  • Cloudflare Worker live-chat relay under worker/
  • YouTube live-chat extraction from all frames
  • canvas danmaku renderer in an extension stage frame over the player
  • right-click menu on a comment: pin and drag it, or hide everything from its author (saved to the NG list)
  • text that grows with the player in fullscreen
  • comments keep flowing when YouTube's chat is closed (a hidden chat frame stands in, replays included)
  • picture-in-picture with comments (beta, Document Picture-in-Picture)
  • JavaScript-only local scorer in extension/scoring.js
  • settings and filter UI
  • local sandbox and renderer performance probes
  • release zip packaging
  • security/supply-chain checks

Browser extraction and rendering are the practical bottlenecks, so scoring is kept small and local.

How It Works

The extension never calls a YouTube API. It reads the chat that YouTube already renders: extension/content.js runs in the watch page and in YouTube's live-chat frame.

  1. The chat frame watches YouTube's live-chat renderer nodes.
  2. Each new message is read from the DOM, checked against the NG lists, and normalized into a ScoreInput.
  3. extension/scoring.js scores it locally: emoji and short reactions flow fast, long text flows slow, and a quality score decides which comments win when the screen is full. Nothing is hidden by the score. The rules, with examples, are in docs/SCORING.md.
  4. buildRenderPlan() maps the result into fast / normal / slow display timing.
  5. A background service worker relays messages from chat frames to the top video frame.
  6. The top frame forwards them to stage.html, an extension frame laid over the YouTube player, where the danmaku.js canvas engine renders them in the extension's own process, off YouTube's main thread. Comments are packed into shared sprite-atlas pages, so the steady state allocates nothing and there is no periodic GC jolt (see docs/PERFORMANCE.md).

The extension does not fetch remote code. The mobile PWA under web/ gets the same chat by polling YouTube's InnerTube API through the Worker relay under worker/. Both paths, with the files and functions involved, are described in ARCHITECTURE.md.

Privacy And Storage

The extension scores, filters, and renders comments locally in the browser. Display, behavior, and performance settings are saved with Chrome Sync storage when available, so Chrome may sync those settings across the signed-in profile. Blocked users and blocked words are saved only in local extension storage on the current device. Chat text, author names, and block lists are not sent to the developer.

Requirements

  • Chrome or Chromium for loading the extension
  • Node.js 22+ and npm 10+ for scripts
  • Optional: Bun 1.3+ for faster local scripts

Install JS tooling:

npm install

Test

Run the security gate, typecheck, web build, unit suites, browser e2e suites when Chromium is installed, and sandbox smoke checks:

npm test

Run the security gate directly:

npm run security

Bun equivalents:

bun run test:bun
bun run security:bun

Renderer performance probe:

npm run test:e2e

Real extension smoke test in Chromium:

npm run test:ext

Opt-in real YouTube smoke:

SYC_REAL_YOUTUBE_URL="https://www.youtube.com/watch?v=..." npm run test:ext:youtube

test:ext opens a real browser locally. In CI it skips by default unless SYC_REQUIRE_EXTENSION_E2E=1 is set. To make npm test fail instead of skipping missing Chromium, set SYC_REQUIRE_E2E=1.

Worker Relay

The Cloudflare Worker under worker/ relays YouTube InnerTube live-chat calls. It defaults to the checked-in WEB client version, but production can override it without a code change:

wrangler deploy --var INNERTUBE_CLIENT_VERSION:2.20260705.00.00

GET /health returns the effective and default InnerTube client versions. GET /health?deep=1&video=<11-char-id> runs a canary next probe with the same effective client version; use it from an external scheduled monitor or Cloudflare Cron Trigger to detect client-version rejection before viewers hit it.

Optional relay controls:

  • ALLOWED_ORIGINS=https://your-pwa.example rejects browser callers from other origins.
  • RATE_LIMIT_PER_MINUTE=120 limits each client IP per Worker isolate; set 0 to disable.

Local Sandbox

Run:

npm run sandbox

Then open:

http://127.0.0.1:4173/

The sandbox serves sandbox/index.html, loads the shared JS scorer, simulates live chat, and renders comments over a fake video surface.

Load In Chrome

Use this path to run the current source instead of the published store build.

  1. Open chrome://extensions.
  2. Enable Developer mode.
  3. Click Load unpacked.
  4. Select the extension directory.
  5. Open a YouTube live stream with live chat.

After changing content scripts or manifest files, reload the extension in chrome://extensions and reload the YouTube tab.

Expected behavior:

  • comments appear over the video in danmaku style
  • short or spammy messages move faster
  • higher-quality or emphasized messages move slower
  • the seekbar-area toggle can hide/show danmaku
  • default YouTube chat hide/show follows settings

Known limitation:

  • YouTube pop-out chat runs in a separate tab without the video player, so this extension does not render pop-out chat messages over the original video tab. Use the normal embedded chat on the watch page for the overlay.

Release Build

Create a tester zip:

npm run release:zip

Bun path:

bun run release:zip:bun

Artifacts are written to .release/, which is ignored by Git. See docs/RELEASE.md.

Store releases go out when a version bump lands on main, through .github/workflows/chrome-webstore-release.yml, which then tags vX.Y.Z and creates the GitHub Release. The store listing and publisher setup is already done; the credentials the workflow needs are in docs/RELEASE.md.

Set package and manifest versions together:

npm run version:set -- 0.1.1

This updates the root, web/, worker/, their lockfile root metadata, and extension/manifest.json.

Documentation

Document Contents
ARCHITECTURE.md how comments are obtained and rendered, code map, repository layout
docs/CONTRACT.md message, poll envelope, and score shapes
docs/SCORING.md how a comment is scored
docs/PERFORMANCE.md measured bottlenecks and their fixes
docs/SECURITY.md threat model and the security gate
docs/PRIVACY.md privacy policy
docs/RELEASE.md release flow and store automation
docs/PLAN.md open work, gates, migration notes
CONTRIBUTING.md setup, checks, boundaries

License

0BSD. You can use, copy, modify, and distribute this project for almost any purpose.

Disclaimer

This project is not developed or distributed as a business, and does not infringe the patent rights of DWANGO Co., Ltd. in Japan.

The developer accepts no liability for any damage arising from this extension.

About

Chrome MV3 and PWA prototype for local-scored YouTube live danmaku overlays

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages