Profile
Back to NewsBack
GitHub Trending 1 min
Reader Mode
naikaku1/YTM_Immersion: YouTube Music向けの拡張機能です。

naikaku1/YTM_Immersion: YouTube Music向けの拡張機能です。

14 hours ago

YTM_Immersion

YouTube Music の Web 版の再生UIをApple Music風の歌詞プレイヤーに変える拡張機能です。


特徴

  • リアルタイム歌詞同期: LRCHubとの連携により、曲に合わせて歌詞が滑らかに追従します。
  • ガラスモーフィズムUI: プレイヤーバーやナビゲーションバーを半透明で浮遊感のあるガラスデザインに統一。
  • 操作性: ImmersionモードOFFで、キューの確認や検索が可能です。
  • 歌詞の翻訳: Deepl APIを所得して、歌詞の翻訳ができるようになります。
  • LRC歌詞表示: LRCファイルを読み込んで、歌詞がない曲も歌詞が出るようになります。
  • 歌詞カード: 聴いている曲の歌詞から 1〜4 行を選んで、ジャケットの色を敷いた画像にできます。ボタン列の「歌詞カード」を押すと、いま歌っている行が選ばれた状態になり、行を押すと範囲を変えられます(選んでいる間は押してもシークしません)。画像は手元で作り、コピーか保存を選びます。どこにも送信しません。

インストール方法 (Installation Guide)

この拡張機能は、Chromeウェブストア版または手動でインストールできます。以下は手動インストール手順です。

1. ファイルのダウンロードと準備

方法1: Gitを使用してリポジトリをクローン

git clone https://github.com/naikaku1/YTM_Immersion

方法2: フォルダをダウンロード(更新に手間がかかります)

  1. 緑色のCodeメニューからDownload Zipを選択します。
  2. ダウンロードされたフォルダを解凍します

2. Chromeでの読み込み手順

  1. お使いのブラウザを開きます。
  2. アドレスバーに chrome://extensions (Chrome/Edge)
  3. 画面右上の 「デベロッパーモード」 (Developer Mode) をONにします。
  4. 左上の 「パッケージ化されていない拡張機能を読み込む」 ボタンをクリックします。
  5. 手順1で解凍した フォルダ全体 を選択して読み込みます。

3. 使い方

  1. YouTube Musicを開き、曲を再生します。
  2. 画面右下のコントロールバーにある [IMMERSION] ボタンをクリックすると、没入モードがON/OFF切り替わります。
  3. ツールバーの拡張機能アイコンや、ショートカットキー Alt+Shift+I(Mac は Option+Shift+I)でも切り替えられます。YouTube Musicの画面が変わってボタンが見当たらない時にも使えます。ショートカットは chrome://extensions/shortcuts で変更できます。

 対応機種について

  • Chromiumをエンジンとする、全てのブラウザ
  • Mac,WIndows,Linuxに対応しますが、Mac上での開発につき、WindowsでのUI崩等が発生する可能性があります。

⚠️ 免責事項と貢献 (Disclaimer & License)

セキュリティと利用について

  • 本拡張機能は、利用者の個人情報やパスワードを収集する仕組みは一切含んでいません。
  • 本拡張機能は、YouTube Musicの閲覧体験を向上させることを目的とした非公式の個人制作物であり、Google LLCとは一切関係ありません。
  • 本拡張機能は MIT License のもとで公開されています。
  • 歌詞の折り返し位置の判定に、Google の BudouX(Apache License 2.0)の日本語モデルを同梱しています(src/js/module/budoux-ja.js)。

貢献について

  • バグ報告や機能改善の提案はいつでも歓迎します。

歌詞の取得について

一般的な歌詞拡張機能は「曲名とアーティスト名の文字列」で外部データベースを検索するため、同名の別曲・ライブ版・カバー版の歌詞を掴んでしまうことがあります。

本拡張機能は再生中の曲を videoId で一意に特定して歌詞を取得します。文字列一致の判断が入る余地がないため、別の曲の歌詞が表示されることがありません。タイミングも配信元のデータをそのまま使うため、音源とずれません。

取得できなかった場合のみ、LRCHub → SimpMusic / LyricsPlus → LrcLib の順にフォールバックします。

取得の流れ

再生中の videoId
  ├─ 歌詞タブの browseId を解決
  ├─ 同期歌詞を取得
  │    └─ 空なら、ログイン済みの状態で再取得
  ├─ それでも駄目なら「曲 ⇔ 動画」の対応を辿る(最大2ホップ)
  ├─ 別リリースをアルバム走査・同名検索で探索(表示は待たせず、裏で実行)
  └─ 見つからなければ LRCHub → SimpMusic / LyricsPlus → LrcLib へ

歌詞の取得元

| 取得元 | 引き方 | 同期の粒度 | | --- | --- | --- | | YouTube Music | videoId | 行 | | LRCHub | videoId / 曲名 | 単語(翻訳・解説つき) | | SimpMusic Lyrics | videoId | 単語 | | LyricsPlus | 曲名・アーティスト・アルバム・尺 | 単語(音節) | | LRCLIB | 曲名・アーティスト | 行 |

LRCHub が歌詞を返せた曲では、追加の取得元は呼び出しません。翻訳や解説は LRCHub の歌詞と同じタイムラインに乗っているため、単語同期が取れるという 理由だけで他の取得元に差し替えることはしません。

いま実際にどこから取得しているかは、マウスを動かすと歌詞の下の ボタン列の真下に出ます(歌詞ソース: LRCHub search / 単語同期 のように、 当たった経路と同期の粒度まで出ます)。手を止めれば数秒で引っ込むので、 聴いている間は画面に何も足しません。押すと取得元の切り替えとズレ直しの メニューが開きます。設定はありません。

デバッグログごと有効にしたい場合は、コンソールで次を実行してから ページを再読み込みしてください。

localStorage.setItem('ytm_debug', '1')  // 元に戻すには removeItem

この値は chrome.storage.local にも写されるので、background (Service Worker)のログも同じ操作で出ます。background 側は起動時にしか 読まないため、切り替えたあとは拡張を読み込み直してください。

歌詞の表示

単語(音節)単位の同期データがある曲では、Apple Music に寄せた表示になります。

  • 境目のぼかしは全角1文字より狭く保つ。 ここを広げると、先端が字を
横切らずに字が丸ごとフェードインしてしまい、それが1文字ずつ順に起きて 「かくんかくん」と点いていくように見えます。
  • 塗りの先端が行をひと続きに流れる。 語ごとに勾配を閉じると語の変わり目で
ぼかしが途切れて境目が見えるので、「行の先頭から何 px 進んだか」を1つだけ 持ち、各語はそこから自分の担当ぶんを描きます。
  • 行そのものは平らなまま。 歌った語を持ち上げたままにすると、語ごとに
高さが違う階段ができて、語と語の間に区切りがあるように見えます。 動くのは伸ばした音だけで、しかも元の高さへ戻します。
  • 伸ばした音だけが膨らんで光る。 全部の語を光らせると行がのっぺり明るくなり、
いま歌っている所が読み取れなくなります。音の長さで強さを決めていて、 速い語はほぼ素通しです。

描画の単位は「文字」ではなく「語」です。1文字ずつ span に切ると文字の間で 字形の詰め(カーニング)が効かず、同じ英文で実測 3.3px 横に伸びて字の間が 空きます。語単位なら 1.4px まで縮みます。空白で区切れない日本語などは ブラウザの語区切り(Intl.Segmenter)でまとめるので、「未だに|あなた|の| こと|を」のように語の中はひと続きに組まれます。塗りの位置は行ぜんたいで 持っているため、単位が語に粗くなっても同期の細かさは落ちません。

塗りの先端は節目(文字ごとの時刻と横位置)を必ず通しつつ、間を3次曲線で 結んでいます。直線で結ぶと、文字は幅がまちまちなのに時間はほぼ等分なので、 細い字は速く太い字は遅く進んで段差になります。

文字の動き(持ち上がり・膨らみ)だけは、毎フレーム JS で transform を 書くのではなく、キーフレームを先に作って Web Animations に渡しています。 Chrome はテキストの縦位置を整数ピクセルに丸める(横は小数対応、縦は非対応) ため、0.05em=32px でも 1.6px しかない移動を JS で書くと 1〜2 回のジャンプに なってしまいます。合成側に渡せば小数のまま動きます。時計合わせは行ごとに 1回で、シークや一時停止でずれた時だけ直します。

折り返しは同期の有無で変わりません。日本語の行は、Google の文節分割 BudouX で文節に切り、文節の途中では 折り返しません。語区切りを助詞の表で繋ぎ直す以前の方式では「何|度でも」 「笑って|み|せた」のように語の途中に切れ目が残っていました。BudouX にも 「笑|顔」のように辞書の語を割る癖があるので、語区切りで1語とされた漢字・ カタカナ語の中では切らないようにしています。行頭に来てはいけない字(小書き 仮名・長音・閉じ括弧・句読点)や「〜て|ゆく」の補助動詞も前に付けます。 英語・中国語・韓国語の行は従来の規則のままです。切り分けは歌詞を描き直す時に 1回だけ行い、1曲あたり 1〜2ms です。

行送りのスクロールはばねで動かしています。ブラウザ内蔵の smooth スクロールは 動いている途中で次の行が来ると今の動きを打ち切って始め直すため、行がつぎつぎ 変わる所で速度が跳ねます。ばねなら目標が変わっても今の速度のまま繋がります (行き過ぎて戻らない臨界減衰)。

動きそのものはブラウザの合成スレッドに任せています。行が変わった時に scrollTop を行き先へ飛ばし、各行を「さっきまでいた位置」から ばねの形の キーフレーム(Web Animations の translate)で戻します。毎フレームの JS は 走らないので、YouTube Music 側が重い瞬間にも歌詞の動きは止まらず、 画面の更新に合わせて滑らかに進みます。

PIP(小窓)でも同じ表示になります。PIP は別ウィンドウ・別文書なので、 語の横位置は向こうの幅で測り直しています。

設定の「Apple Music 風の文字同期」で従来の点灯式に戻せます (低負荷モード中は自動で従来式になります)。

表示速度のための工夫

  • 再生中のキューの数曲先まで歌詞を先読み(曲送り時は待ち時間ゼロ)
  • 曲をクリックした瞬間に取得を開始
  • ページを開いた直後は URL から videoId を読んで即座に取得開始
  • 取得結果は videoId 単位でキャッシュ

開発

ビルド不要です。ソースをそのまま読み込みます。

# 構文チェック
for f in src/js/.js src/js/module/.js; do node --check "$f"; done

テスト (Node 24 ではディレクトリ指定が効かないので glob で渡す)

node --test tests/*.test.mjs

コミュニティ

要望・不具合報告・雑談は Discord へどうぞ。


プライバシー

個人を特定できる情報の収集は行っていません。通信先と送信内容、ログイン状態の扱いについては Privacy.md に記載しています。

歌詞データの著作権は各権利者に帰属します。本拡張機能は歌詞データを保有・配信するものではなく、取得した内容を表示するのみです。

Chat with me