YouTube 公式アプリと同期する、見るだけのフローティングチャットビューワー(Android)。
公式アプリで動画を視聴しながら、その動画のチャット(チャットリプレイ)をフローティングウィンドウで表示します。 公式アプリの再生位置を自動で読み取り、チャットの投稿時刻(動画内の位置)に合わせて流します。 コメントの投稿など、書き込みの機能は持ちません(名前は ROM=Read Only Member +チャット から)。
YouTube 公式アプリは、動画を小窓(フローティング/PiP)にして他のアプリを使えますが、小窓の状態ではチャット(コメント)が 見えなくなります。小窓で動画を流したままチャットも追いたい、つまりフローティングに対応したチャットビューワーが欲しい、 というのが本アプリを作った動機です。そこで、公式アプリの再生位置を読み取り、チャットを別のフローティングウィンドウへ 同期して表示する形にしました。
Important
本アプリは非公式のアプリで、YouTube および Google とは関係ありません。チャットの取得には公開されていない方法 (YouTube の Web 版が内部で使う通信)を使っているため、YouTube の仕様変更により予告なく動かなくなることがあります。 YouTube の利用規約上の位置付けも公式 API とは異なります。自己の判断と責任で利用してください。
v1.2.0(M5 配布)。計画と要件は docs/PLAN.md を参照してください。
| 機能 | 状態 |
|---|---|
| アーカイブ(ライブ配信・プレミア公開の終了後)のチャットリプレイの同期表示 | 実装済み |
| 公式アプリで再生中の動画の自動特定(MediaSession・端末内キャッシュ・検索照合) | 実装済み |
| 公式アプリの「共有」・URL 入力による動画の指定 | 実装済み |
| フローティングウィンドウ(移動・サイズ変更・背景の透過度・自動スクロール・常駐通知) | 実装済み |
| ライブ配信・プレミア公開中(待機中を含む)のチャット追従、表示遅延の設定、終了後のリプレイへの切り替え | 実装済み(終了後の切り替えは実機確認待ち) |
| 他アプリに音声を奪われて止まった YouTube の再開ボタン、一時停止からの自動再開(既定オフ) | 実装済み |
| タッチ透過・最小化・画面端への退避・縦横別の位置記憶・同期の手動補正・手動タイマー | 実装済み |
| 文字サイズ・投稿者名/アイコン/時刻の表示・絞り込み(NG ワード等)・表示件数・上位チャット・テーマ・絵文字画像 | 実装済み |
| 設定画面(表示設定・バックアップ・クラッシュ情報の送信・キャッシュの消去・設定の初期化・更新の確認)と、右上の歯車・三点メニュー | 実装済み |
| 表示言語の切り替え(日本語・English。既定は日本語) | 実装済み |
| 配信直後でチャットが未生成の動画の案内と自動再確認 | 実装済み |
| 更新の確認(手動)・署名済み APK の配布 | 実装済み(v1.2.0 を配布) |
- GitHub Releases から
romcha-vX.Y.Z.apkをダウンロードします。 - 必要なら、同じページの
romcha-vX.Y.Z.apk.sha256の値とダウンロードしたファイルの SHA-256 が一致することを確かめます。 - 端末で APK を開いてインストールします(ブラウザー等に「不明なアプリのインストール」の許可が必要です)。
Google Play では配布していません。更新はアプリの「更新を確認」で確かめ、新しい版を同じ手順で上書きインストールします (設定は引き継がれます)。Obtainium 等の GitHub のリリースを追従するインストーラも使えます。
-
アプリを起動し、画面の案内に従って次の権限を許可します。
- 他のアプリの上に重ねて表示: チャットのウィンドウを公式アプリの上に表示するため(必須)。
- 通知へのアクセス: 公式アプリの再生位置(再生中の動画・位置・速度)を読み取るため。
Android の仕組み上この名前の権限ですが、本アプリは通知の内容を読みません
(
MediaSessionManager.getActiveSessionsを呼ぶ条件としてのみ使います)。 - 通知の表示: 表示中であることを示す常駐通知と、そこからの表示切り替え・終了のため。
すべて許可すると「すべて許可済みです」の 1 行にまとまります(「詳細を表示」で各権限を確認できます)。
-
「フローティング表示を開始」を押し、公式アプリでアーカイブ動画を再生します。
-
再生中の動画を自動で特定してチャットを表示します。特定できない場合は候補から選ぶか、 公式アプリの「共有」で Romcha を選ぶ、またはアプリの「URL で開く」に動画の URL を入力してください。 ウィンドウ上部の帯は状態のお知らせで、灰色は案内(読み込み中・特定中・再接続中など)、赤は失敗(通信できない・ チャットを利用できない等)です。表示するチャットがまだ無い時や、絞り込みですべて隠れた時は一覧の中央にその旨を出します。 配信が終わった直後のアーカイブは、YouTube がチャットのリプレイを作るまで(数時間かかることがあります)読み込めません。 その場合は「チャットはまだ利用できません」と案内し、約 18 分まで自動で再確認します。
-
ライブ配信・プレミア公開中は最新のチャットを追従して表示します。チャットが映像より先に流れる場合は、 ウィンドウの設定ボタンから表示の遅延(0〜30 秒)を設定できます。配信が終わると、リプレイの準備ができ次第 再生位置に同期した表示へ切り替わります。
-
ウィンドウのヘッダー(色の付いた帯)をドラッグで移動、右下のつまみで大きさを変えられます。位置と大きさは画面の縦・横それぞれで 記憶します。ヘッダーのボタンは左から再開(一時停止中だけ押せます)・設定・最小化(丸いバブルになり、タップで戻る)・隠す(常駐通知から再表示)です。 ヘッダーをつかんでウィンドウを画面の左右の外へ運んで離すと、画面端に細いつまみだけを残して退避します (YouTube 公式アプリの小窓と同じ操作)。つまみを画面の内側へスワイプするか、タップすると元に戻ります。
-
設定ボタンでは次を変えられます。
- 背景の透過度(ヘッダーとチャット欄の両方に効きます)と、チャットの文字サイズ(80〜150%)。
- リプレイの表示タイミングの補正(±10 秒、0.5 秒刻み。+でチャットを早く表示)。
- 手動タイマー: 公式アプリの再生位置が取れない時に、開始・停止・位置の入力でチャットを進めます。
- タッチ透過: ウィンドウ越しに公式アプリを操作できるようにします。解除は常駐通知の「タッチ透過を解除」から行います。
- アプリを開く: Romcha の画面(URL 入力など。設定は右上の歯車から)を開きます。ウィンドウは表示したまま残ります。
-
アプリの右上の歯車(設定)→「表示設定」では、投稿者名・アイコン・時刻の表示、テーマ、「上位のチャットのみ」、絞り込み(スーパーチャットのみ・ メンバーのみ・モデレーター/配信者のみ・NG ワード)、表示する件数の上限、ヘッダーのボタンの大きさ(「ヘッダーのボタンを大きくする」で 押しやすい大きさに。代わりにタイトル欄が狭くなります)を変えられます。変更は表示中のウィンドウへすぐ反映します。 他のアプリに音声を奪われて YouTube が一時停止した時は、ヘッダーの再生ボタン(一時停止中だけ押せます)で再開できます。押しても前面のアプリの 操作は妨げません。「一時停止したら自動で再開する」(既定はオフ)をオンにすると、一時停止の 2 秒後に自動で再開します(30 秒に 3 回まで)。 自分で一時停止した場合との区別はできないため、その場合も再開されます。結果は診断情報の画面で確かめられます。
-
「URL で開く」の「クリップボードから貼り付け」は、押した時だけクリップボードを読みます。 別の動画のチャットが出る時は、アプリの右上の歯車(設定)→「キャッシュを消す」で、特定済みの動画の対応を消して特定し直せます。
-
アプリの「更新を確認」を押すと、GitHub で公開されている最新版の番号を確かめます。新しい版があれば 「ダウンロードページを開く」からリリースのページを開けます(自動では確認・インストールしません)。
-
表示言語は日本語と English に対応しています。既定は日本語で、アプリの右上の歯車(設定)→「言語」で切り替えます (フローティングウィンドウの表示も切り替わります)。
画面がオフの間、公式アプリが一時停止している間はチャットの取得を止めます。
- 広告の再生中は同期がずれることがあります(YouTube Premium に加入していない場合)。公式アプリは広告中も動画のタイトル・ 長さをそのまま公開し、再生位置だけが広告自体の位置(0 秒から)になるため、本アプリからは広告と本編を区別できません。 広告の間は動画の冒頭付近のチャットが表示されることがあり、広告が終わると再生位置に合わせて表示し直します。
- Android 14(API 34)以上。動作確認端末は Pixel 8 Pro(Android 17、YouTube 21.38.130、Premium 有り/無し)。
- YouTube 公式アプリ(
com.google.android.youtube)。
- JDK 17
- Android SDK(compileSdk 36。
ANDROID_HOMEまたはlocal.propertiesのsdk.dirで指定) - Node.js(Markdown の静的解析
markdownlint-cli2をnpxで実行する場合) - Python 3 と PyYAML(記録ファイルの検証
scripts/validate-records.py)
# デバッグ APK(app/build/outputs/apk/debug/app-debug.apk)
./gradlew :app:assembleDebug
# 静的解析(ktlint・detekt・Android lint)
./gradlew ktlintCheck detekt lintDebug
# 型検査
./gradlew compileDebugKotlin
# 単体テスト
./gradlew testDebugUnitTest :core:chat:test :core:sync:testリリース APK は scripts\release-build.bat(Windows。署名情報の確認・品質ゲート・署名の確認までをまとめて行う)
または ./gradlew :app:releaseDist で app/build/dist/ に romcha-vX.Y.Z.apk と SHA-256(.sha256)を出力します。
署名にはリポジトリのルートの local.properties(.gitignore で除外済み)に RELEASE_STORE_FILE・RELEASE_STORE_PASSWORD・
RELEASE_KEY_ALIAS・RELEASE_KEY_PASSWORD が必要で、無い場合は未署名の romcha-vX.Y.Z-unsigned.apk になります。
鍵の作成から Releases での公開までの手順は docs/RELEASE.md を参照してください。
Windows の PowerShell では ./gradlew を .\gradlew.bat と読み替えてください。
品質ゲートの正本は CLAUDE.md「本リポジトリの品質ゲート定義」です。
ktlint の指摘は ./gradlew ktlintFormat で自動修正できます。
adb install -r app/build/outputs/apk/debug/app-debug.apk実機での検証手順は docs/VERIFICATION.md を参照してください。
| モジュール | 内容 |
|---|---|
app |
起動画面(権限案内・URL 入力・共有の受信・免責・OSS ライセンス・診断情報) |
core:chat |
InnerTube クライアント、チャット応答の解析、動画の自動特定(Kotlin/JVM) |
core:sync |
再生位置とチャットの同期(Kotlin/JVM) |
core:media |
公式アプリの MediaSession の監視 |
feature:overlay |
フローティングウィンドウ、セッション統合 |
設計の詳細は docs/records/managed/DESIGN.md を参照してください。
アプリを紹介するポートフォリオ(静的な 1 ページ。他アプリのテンプレートを兼ねる)の原本は site/ にあり、
GitHub Pages(https://filderschoice.github.io/romcha/)で公開します。
チャット取得の単体テストは、既知の応答構造に基づく合成データ(core/chat/src/test/resources/fixtures/)と
MockWebServer で行い、YouTube へは通信しません。実際の応答から作ったデータ(fixtures/real/、投稿者・配信者・動画の情報は置き換え済み)
でも解析を確かめています。このデータは python scripts/fetch-real-fixtures.py --replay <動画ID> で作り直せます
(YouTube へ通信します)。
アプリの右上の三点メニュー →「診断情報」で、公式アプリの MediaSession が公開している値(状態・位置・速度・メタデータの全キー)を 確認できます。表示は端末の画面内のみで、外部へは送信しません。
- ログイン機能はありません。広告・利用状況の解析の SDK は含みません(クラッシュ情報の送信のみ。下記)。
- 通信先は YouTube(
www.youtube.com)と、カスタム絵文字・スタンプなどの画像を配信する YouTube の画像配信元 (*.ggpht.com・*.ytimg.com・*.googleusercontent.com。HTTPS のみ)と、「更新を確認」を押した時の GitHub API(api.github.com。最新リリースの版番号を読むだけで、認証情報は送りません)と、下記のクラッシュ情報の送信先だけです。 - クラッシュ情報は、アプリが異常終了した時に Google の Firebase Crashlytics へ送ります。送る内容はエラーの内容(スタックトレース)・
アプリの版・Android の版・端末の機種・匿名のインストール識別子で、チャットの内容や動画の URL は送りません。
既定でオンです。アプリの設定画面の「クラッシュ情報を送信する」のスイッチでいつでもオフにでき、オフにするとそれ以降は送りません。
自分でビルドした場合は、
app/google-services.jsonが無ければ送信の機能自体が無効です。 - 動画の特定結果のキャッシュは端末内にのみ保存し、バックアップの対象外にしています。ウィンドウの設定・表示の絞り込み・NG ワード・ クラッシュ情報の送信の可否は、再インストール時に復元できるよう Android の自動バックアップ(Google アカウントのバックアップ)の対象です。 アプリの設定画面の「設定をバックアップする」のスイッチでオフにでき、「設定を初期化する」で設定を初期値へ戻せます。
不具合の報告・要望は GitHub Issues へお寄せください。 本アプリは非公式のアプリのため、YouTube・Google へは問い合わせないでください。
- 報告には、アプリの版(「アップデート」欄)・Android の版・YouTube 公式アプリの版と、起きたことを書いてください。 アプリの「診断情報」の内容を添えると調査が速くなります(再生中の動画のタイトル等が含まれるため、必要に応じて伏せてください)。
- 報告は公開されます。アカウント名・メールアドレス・視聴履歴など、個人に関わる情報は書かないでください (スクリーンショットに写る配信者名・チャットの投稿者名も、必要がなければ隠してください)。
- 脆弱性と思われる問題の報告方法は
SECURITY.mdを参照してください。
MIT License。参考にした外部実装の記録は docs/REFERENCES.md、
依存ライブラリのライセンスはアプリ内の「オープンソースライセンス」画面で確認できます。