{"id":50815316,"url":"https://github.com/shinshin86/chrome-on-aituber","last_synced_at":"2026-06-13T09:01:17.178Z","repository":{"id":344368491,"uuid":"1178604302","full_name":"shinshin86/chrome-on-aituber","owner":"shinshin86","description":"Browser-only AITuber chat app built with React and Vite. It uses Chrome Built-in AI (Gemini Nano / Prompt API) for Japanese responses, piper-plus WASM for speech synthesis, and a 4-sprite avatar for lip-sync and blinking animation.","archived":false,"fork":false,"pushed_at":"2026-03-14T10:04:49.000Z","size":9861,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-14T20:47:56.161Z","etag":null,"topics":["aicharacter","aituber"],"latest_commit_sha":null,"homepage":"https://shinshin86.github.io/chrome-on-aituber/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shinshin86.png","metadata":{"files":{"readme":"README.ja.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-11T07:21:45.000Z","updated_at":"2026-03-14T14:56:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shinshin86/chrome-on-aituber","commit_stats":null,"previous_names":["shinshin86/chrome-on-aituber"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/shinshin86/chrome-on-aituber","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shinshin86%2Fchrome-on-aituber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shinshin86%2Fchrome-on-aituber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shinshin86%2Fchrome-on-aituber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shinshin86%2Fchrome-on-aituber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shinshin86","download_url":"https://codeload.github.com/shinshin86/chrome-on-aituber/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shinshin86%2Fchrome-on-aituber/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34278154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aicharacter","aituber"],"created_at":"2026-06-13T09:00:57.627Z","updated_at":"2026-06-13T09:01:17.173Z","avatar_url":"https://github.com/shinshin86.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chrome on AITuber\n\nReact + Vite で構成された、ブラウザ完結型の AITuber チャットアプリです。Chrome Built-in AI（Gemini Nano / Prompt API）で日本語応答を生成し、piper-plus WASM で音声合成し、4 枚スプライトのアバターを口パクとまばたき付きで表示します。\n\n[English README](./README.md)\n\n## 機能\n\n- アプリケーションサーバー不要のブラウザ完結動作\n- Chrome Built-in AI / `LanguageModel` による日本語チャット\n- piper-plus WASM + OpenJTalk + ONNX Runtime Web による音声合成\n- 4 枚スプライトのアバター表示、口パク、ランダムまばたき\n- 背景画像の変更とデフォルト背景への復帰\n- チャットモードと配信モード（グリーンバック）の 2 表示モード\n- YouTube Data API v3 を使った YouTube Live コメント取得\n- EventSub WebSocket + OAuth implicit flow を使った Twitch コメント取得\n- 4 枚画像アップロードによるカスタムアバター登録\n- `localStorage` への設定・会話履歴保存\n- `IndexedDB` へのカスタムアバター保存\n\n## 必要環境\n\n- Google Chrome 138 以降\n- Node.js 18 以降\n- `npm`\n\nAI 応答を使うには、事前に Chrome Built-in AI を有効化してください。\n\n1. `chrome://flags` を開く\n2. `#optimization-guide-on-device-model` を有効化\n3. `#prompt-api-for-gemini-nano` を有効化\n4. Chrome を再起動\n5. オンデバイスモデルのダウンロード完了を待つ\n\n初回起動時にモデルがまだ端末へ入っていない場合、Chrome の制約でモデル準備の開始にはユーザー操作が必要です。アプリ上に表示される `AI を準備` ボタンを押してから利用してください。\n\n## セットアップ\n\n1. リポジトリを clone して依存関係を入れる\n\n```bash\ngit clone https://github.com/shinshin86/chrome-on-aituber.git\ncd chrome-on-aituber\nnpm install\n```\n\n2. 音声を使いたい場合は TTS アセットを配置する\n\npiper TTS の完全なアセット一式は、このリポジトリにはコミットされていません。自分で clone して起動する場合は、必要なファイルを `public/piper/` 配下に配置する必要があります。\n\nGit 管理されているのは次のみです。\n\n- `public/piper/piper-global-loader.js`\n\nそれ以外の `public/piper/` 一式は利用者側で別途用意する必要があります。これらがない場合でもチャット画面は開けますが、TTS は正常動作しません。\n\n次の手順でアセットを用意してください。\n\n1. [ayutaz/piper-plus](https://github.com/ayutaz/piper-plus) から `piper-plus` を取得\n   `dev` ブランチを clone またはダウンロードし、次をコピーします。\n   - `src/wasm/openjtalk-web/dist/` -\u003e `public/piper/dist/`\n   - `src/wasm/openjtalk-web/src/` -\u003e `public/piper/src/`\n   - `src/wasm/openjtalk-web/assets/` -\u003e `public/piper/assets/`\n2. [onnxruntime-web の npm ページ](https://www.npmjs.com/package/onnxruntime-web) から `onnxruntime-web` を取得\n   次のファイルを `public/piper/dist/` に配置します。\n   - `dist/ort.min.js`\n   - `dist/ort-wasm.wasm`\n   - `dist/ort-wasm-simd.wasm`\n3. [ayousanz/piper-plus-tsukuyomi-chan](https://huggingface.co/ayousanz/piper-plus-tsukuyomi-chan) から音声モデルを取得\n   次のファイルを `public/piper/models/` に配置します。\n   - `tsukuyomi-wavlm-300epoch.onnx`\n   - `config.json` を `tsukuyomi-config.json` にリネームしたもの\n4. ライセンス表記\n   `scripts/package-piper-assets.sh` は、パッケージ前に `scripts/piper/licenses/` のテンプレートを `public/piper/licenses/` にコピーします。手動で `public/piper/` を組み立てる場合も、このディレクトリを同梱してください。\n\nPiper 音声モデルのクレジット:\n\n\u003e 本ソフトウェアの音声合成には、フリー素材キャラクター「つくよみちゃん」(c) Rei Yumesaki が無料公開している音声データを使用しています。\n\u003e\n\u003e つくよみちゃんコーパス（CV.夢前黎）\u003cbr\u003e\n\u003e https://tyc.rei-yumesaki.net/material/corpus/\n\n`scripts/package-piper-assets.sh` はセットアップ用スクリプトではなく、すでに用意済みの `public/piper/` にライセンステンプレートをコピーした上で `piper-assets.tar.gz` に固めて GitHub Releases / CI 配布に使うためのものです。`scripts/release-piper-assets.sh` はさらに GitHub Release へのアップロードまで自動化します。\n\nどちらも `gh` で GitHub にログイン済みのローカル作業環境で使う想定です。\n\nこのパッケージ化フローを使う場合は、次を実行してください。\n\n```bash\n./scripts/package-piper-assets.sh\n./scripts/release-piper-assets.sh\n```\n\n既存の `piper-assets-v1` release asset には `piper/licenses/` が含まれていません。このテンプレート込みで tarball を作り直した後は、新しい release asset を公開し、GitHub Actions の repository variable `PIPER_ASSETS_URL` を新しい URL に更新してください。\n\nIrodori TTS を使う場合は、別途 `public/irodori/` に Irodori 用の `manifest.json`、WebGPU 向け fp16 ONNX モデル、tokenizer、`runtime/pipeline.mjs`、ライセンス文を配置します。このディレクトリは Git 管理対象外です。組み上げ手順は [`scripts/irodori/`](scripts/irodori/README.md) にあります。\n\nデプロイ先では、アセット一式（約 1.3GB）が GitHub Pages のサイト上限を超えること、および GitHub Release asset には CORS ヘッダが付かないことから、Irodori アセットは二分割でホスティングします。ランタイム（`pipeline.mjs` + ONNX Runtime wasm。dynamic `import()` に JavaScript の MIME タイプが必要なため同一オリジン配信）は GitHub Release の tarball としてビルド時に展開され（`IRODORI_RUNTIME_ASSETS_URL`）、モデルと tokenizer はブラウザが公開 Hugging Face リポジトリから直接ダウンロードします（`IRODORI_ASSETS_BASE_URL` → `VITE_IRODORI_ASSETS_BASE_URL`）。どちらの repository variable も任意で、未設定時は同一オリジンの `irodori/` に fallback します。リリース手順は [`scripts/irodori/README.md`](scripts/irodori/README.md) を参照してください。\n\nアプリ上で `Irodori TTS モデルをダウンロード` を押すと、モデル一式はブラウザストレージ（主に IndexedDB）に保存されます。現在の fp16 アセット一式は約 1.2 GiB です。通常ウィンドウでは、設定画面の `モデルを削除して容量を解放` を押すか、Chrome のサイトデータを削除するまで残ります。シークレットモードでは、そのシークレットセッション用の一時保存になり、すべてのシークレットウィンドウを閉じると Web アプリからは参照できなくなります。また、シークレットモードは保存容量の上限が通常ウィンドウより小さくなることがあり、モデル保存が `QuotaExceededError` で失敗する場合があります。参照音声としてアップロードした `.wav` は永続保存されず、セッション内のメモリ上でのみ使われます。\n\n3. 開発サーバーを起動する\n\n```bash\nnpm run dev\n```\n\nChrome で Vite の URL（通常は `http://localhost:5173`）を開いてください。\n\n## 使い方\n\n- 画面下の入力欄にテキストを入れて `Enter` で送信\n- 初回のみ、必要に応じて `AI を準備` を押して Gemini Nano のモデル準備を開始\n- 改行は `Shift+Enter`\n- 下部バーから設定パネルを開く\n- `Ctrl+S` / `Cmd+S` で設定パネルを素早く開閉\n- 配信モードに切り替えると、中央アバターのみのグリーンバック表示\n- 設定パネルから会話リセット、TTS の ON/OFF、読み上げ速度変更が可能\n- 設定パネルから背景画像を変更でき、`デフォルトに戻す` で元の背景に戻せる\n- カスタムアバターは 4 枚の画像を登録して追加可能\n  - 口閉じ・目開き\n  - 口閉じ・目閉じ\n  - 口開き・目開き\n  - 口開き・目閉じ\n\n## 配信コメント連携\n\n### YouTube Live\n\n設定パネルで次を設定します。\n\n- `YouTube API Key`\n- `ライブ配信 ID`\n- コメント取得間隔\n- 有効化チェック\n\n`ライブ配信 ID` は YouTube 配信 URL の動画 ID です。例:\n\n- `https://www.youtube.com/watch?v=dQw4w9WgXcQ` -\u003e `dQw4w9WgXcQ`\n\nブラウザから直接ライブチャットを取得し、重複や古いコメントを除外したうえで、1 件を選んで AI に渡します。\n\n### Twitch\n\n設定パネルで次を設定します。\n\n- `Twitch Client ID`\n- チャンネル名\n- コメント取得間隔\n\nその後 `Twitch に接続` を押して OAuth を完了すると、ブラウザ内でアクセストークンを保持し、EventSub WebSocket の `channel.chat.message` を購読します。\n\n## ビルド\n\n```bash\nnpm run build\nnpm run preview\n```\n\nVite の開発サーバーでは、すでに次のヘッダーを返しています。\n\n- `Cross-Origin-Opener-Policy: same-origin`\n- `Cross-Origin-Embedder-Policy: require-corp`\n\n本番ホスティングでも、WASM / `SharedArrayBuffer` のために同じヘッダー設定が必要です。\n\n## プロジェクト構成\n\n```text\nsrc/\n├── components/\n│   ├── Avatar/\n│   ├── Chat/\n│   ├── License/\n│   ├── Manual/\n│   ├── Settings/\n│   └── Toast/\n├── hooks/\n│   ├── useBlink.ts\n│   ├── useChat.ts\n│   ├── useInterval.ts\n│   ├── useSettings.ts\n│   ├── useTwitchComments.ts\n│   └── useYoutubeComments.ts\n├── services/\n│   ├── avatar/\n│   ├── llm/\n│   ├── storage/\n│   ├── tts/\n│   ├── twitch/\n│   └── youtube/\n└── types/\n```\n\n## 補足\n\n- 設定、会話履歴、API キー、Twitch アクセストークンはローカルブラウザに保存されます。\n- Irodori TTS のダウンロード済みモデルはブラウザストレージに保存されるため、保存容量を約 1.2 GiB 使用します。\n- シークレットモードでは保存容量の上限が小さくなる場合があるため、Irodori TTS のモデル保存には通常ウィンドウの利用を推奨します。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshinshin86%2Fchrome-on-aituber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshinshin86%2Fchrome-on-aituber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshinshin86%2Fchrome-on-aituber/lists"}