Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
YouTubeのチャット欄の配置変更 / Changing the layout of the...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Atom
June 28, 2026
Programming
45
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
YouTubeのチャット欄の配置変更 / Changing the layout of the YouTube chat field
chrome拡張機能:
https://github.com/yAtomtom/youtube-chat-rearranger
Atom
June 28, 2026
More Decks by Atom
See All by Atom
Tauri v2で作る⼀括画像ブラー / Bulk image blur created with Tauri v2
roraidolaurent
0
20
文献紹介 / Structure-based Knowledge Tracing: An Influence Propagation View
roraidolaurent
0
130
文献紹介 / Knowledge Tracing with GNN
roraidolaurent
0
110
文献紹介 / Non-Intrusive Parametric Reduced Order Models withHigh-Dimensional Inputs via Gradient-Free Active Subspace
roraidolaurent
0
79
ニューラルネットワークのベイズ推論 / Bayesian inference of neural networks
roraidolaurent
2
2.9k
Graph Convolutional Networks
roraidolaurent
0
270
文献紹介 / A Probabilistic Annotation Model for Crowdsourcing Coreference
roraidolaurent
0
100
文献紹介Deep Temporal-Recurrent-Replicated-Softmax for Topical Trends over Time
roraidolaurent
0
160
文献紹介/ Bayesian Learning for Neural Dependency Parsing
roraidolaurent
0
150
Other Decks in Programming
See All in Programming
すこし踏み込む CancellationToken
htkym
2
710
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
300
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
150
Java 27新機能 / Java 27 new features
kishida
2
150
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
5
3.8k
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
120
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
250
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
8
6.8k
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
290
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
110
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
330
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.2k
Featured
See All Featured
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
From π to Pie charts
rasagy
1
370
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
900
Producing Creativity
orderedlist
PRO
348
41k
The agentic SEO stack - context over prompts
schlessera
0
940
The Mindset for Success: Future Career Progression
greggifford
PRO
0
500
A designer walks into a library…
pauljervisheath
211
25k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Speed Design
sergeychernyshev
33
2.1k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
4 Signs Your Business is Dying
shpigford
187
23k
Transcript
YouTube のチャット欄の配置を変更してみた WQHD での複窓のためのchrome 拡張機能 吉澤亜斗武 1
内容 背景 YouTube のレイアウト Chrome 拡張機能の作成の基本 チャット欄の配置を変更する まとめ 付録 2
背景 3
YouTube での複数の動画を視聴 フルHD の場合 4
YouTube での複数の動画を視聴 (WQHD) 新しいモニターを買ったら... 5
YouTube はページ幅が1000px を境にレイアウトが変わります 横並びで複窓(2 窓)にする時WQHD ではチャット欄が動画プレイヤー横にくるための 動画プレイヤーのサイズが小さくなります 画面幅 1 窓辺りの幅
チャット欄の位置 動画プレイヤーの横幅 フルHD 1920 960 動画プレイヤーの下 945 WQHD 2560 1280 動画プレイヤーの横 791 6
目的 WQHD での複窓の際に動画プレイヤーをフルHD の複窓表示より大きくしたい チャット欄はニコニコ風に表示する別拡張機能 の関係でDOM 自体は削除したく ない → チャット欄の配置を変更するchrome
拡張機能を作ろう 1 1: Flow Chat for YouTube Live 7
成果物 chrome 拡張機能: https://github.com/yAtomtom/youtube-chat-rearranger 動画が幅に対して真ん中に表示されます. 8
YouTube のレイアウト 9
基本構成 <ytd-watch-flexy> <div id="full-bleed-container" class="style-scope ytd-watch-flexy"> ... </div> <div id="columns"
class="style-scope ytd-watch-flexy"> <div id="primary" class="style-scope ytd-watch-flexy"> ... </div> <div id="secondary" class="style-scope ytd-watch-flexy"> ... </div> </div> </ytd-watch-flexy> 10
two columns layout full-bleed-container は表示されずに2 カラム表示になる primary, secondary は幅の上限やマージンが存在する 11
single column layout secondary は表示されずにfull-bleed-container とprimary で1 カラム表示になる full-bleed-container は幅の上限やマージンがなくシアターモードでも使用される
12
戦略候補: DOM 移動 vs CSS 変更 チャット欄( #secondary ) を動画下に持ってくる方法は大きく2
通り 観点 DOM 移動 CSS 変更(CSS Grid ) やり方 secondary を primary の子へ移動 #columns にGrid を当て見た目だけ再配置 DOM 構造 変わる 不変( display: contents で透明化) iframe チャット 再挿入で壊れる( about:blank ) 影響なし 仕様変更への強さ 弱い( src の自前再構築が必要) 強い → DOM 移動には iframe が壊れる落とし穴がある.本稿では DOM 移動を試みた後 CSS Grid で見た目だけ変える方法を紹介する 13
拡張機能の作り方 14
manifest.json の例 manifest.json を含むプロジェクトフォルダを chrome://extensions/ から読み込めばよ い { "name": "YouTube
Chat Rearranger", "version": "1.2", "manifest_version": 3, "description": "ライブ・アーカイブでYouTubeチャット欄をbelow(説明欄,コメント欄)と横並びにします", "permissions": ["storage"], "action": { "default_title": "YouTube Layout Modifier", "default_popup": "popup.html" }, "content_scripts": [ { "matches": ["*://www.youtube.com/watch*"], "js": ["content.bundle.js"], "css": ["styles/layout.css"], "run_at": "document_end" } ] } 15
manifest.json のkey の例 manifest_version マニフェスト ファイル形式のバージョン. 使用できるkey やブラウザによって対応状況が違う content_scripts URL
がマッチしている場合にjs やCSS を読み込む (今回は js にバンドル、 css にレイアウト定義 styles/layout.css を指定) run_at: document_end でDOM 構築直後に読み込む action ツールバーの拡張機能アイコンに外観や動作を定義 参考 https://developer.chrome.com/docs/extensions/reference/manifest https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json 16
チャット欄の配置を変更する 17
まずは DOM 移動を試す 18
コード例(DOM 移動・試行) const player = document.getElementById('player'); const below = document.getElementById('below');
const secondary = document.getElementById('secondary'); // 新しいレイアウト用ラッパー const layout = document.createElement('div') // layout に below, secondary を移動 layout.appendChild(below); layout.appendChild(secondary); // layout を player の直後に挿入 const parent = player.parentNode; // primary parent.insertBefore(layout, player.nextSibling); 19
DOM 移動するとチャット欄が表示されない. . . 20
なぜ壊れるか: iframe.contentWindow.location.href チャット欄は iframe ( #chatframe ) 。DOM 移動で再挿入されると navigable
が作り直さ れるのが原因. HTML(Living Standard) の仕様上、再挿入された iframe は src 属性を持たないと contentWindow.location.href が about:blank になる(中身が空に) . <iframe id="chatframe" class="style-scope ytd-live-chat-frame"> #document(about:blank) <html><head></head><body></body></html> </iframe> 切り離し時のchild navigable の削除 挿入時のiframe attribute の処理 21
回避策(src 再構築)と、その限界 壊れた iframe の src を自前で再構築すれば一応直せる( live_chat?v=... を設定す るなど)
. しかしこの方針は脆い: アーカイブでは live_chat_replay?continuation=... とパラメータが変わり、トー クン抽出が必要 YouTube 側の仕様変更に追従し続ける必要がある そもそも iframe を再挿入したことが問題の根源 → DOM を動かさなければ iframe は壊れない.見た目だけ CSS で変えればよい. 22
採用案: DOM を動かさず CSS Grid で再配置 #columns に .ytcr-active を付け、
#primary / #primary-inner を display: contents で“ 透明化” すると、子の #below / #secondary が直接 grid item になる (DOM は不動) . #columns.ytcr-active { display: grid !important; grid-template-columns: 2fr 1fr; grid-template-areas: "player player" "below secondary"; } /* primary を透明化して子を grid item に昇格 */ #columns.ytcr-active > #primary, #columns.ytcr-active #primary-inner { display: contents !important; } #columns.ytcr-active #player { grid-area: player; } #columns.ytcr-active #below { grid-area: below; } #columns.ytcr-active > #secondary { grid-area: secondary; } 23
表示OK 24
まとめ 目的: WQHD の複窓で動画を大きくしたい。ただしチャット欄の DOM は残した い DOM 移動だと iframe
( #chatframe ) が再挿入で about:blank になりチャットが壊 れる → DOM を動かさず CSS Grid ( display: contents )で見た目だけ再配置して回避 25
付録 26
1. continuation ライブ配信ではGET を常に連続して叩くことでチャットを取得しているが アーカイブ動画ではcontinuation というトークンを基に一定間隔で効率的に取得 リプレイ表示ボタンを押すと、YouTube 本体がこのトークンを使ってチャットをまと め取得する(DOM 移動時は自前で取得し直す必要がある)
. GET のレスポンスbody (抜粋): "continuationContents": { "liveChatContinuation": { "continuations": [ { "liveChatReplayContinuationData": { "timeUntilLastMessageMsec": 5000, "continuation": "op2w0wR8Gl5DaWtxSndvWVZVT...." } }, ... ], "actions": [...] } } 27
2. DOM 変更によるバグの例 シークバーを動かすと薄暗い映像が部分的に表示 28
とりあえずhtml をみてみる <div class="ytp-storyboard-framepreview" data-layer="4" style=""> <div class="ytp-storyboard-framepreview-timestamp">1:09:48</div> <div class="ytp-storyboard-framepreview-img"
style=" width: 697.084px; height: 393px; margin: 0px 1px 0px 0px; background: url('https://i.ytimg.com/sb/KU0qH-UmXfg/storyboard3_L3/M46.jpg?sqp=xxx&sigh=yyy') -1396px -393px / 2094px 1179px; "> </div> </div> 29
storyboard スプライト画像の一つで、複数の画像を1 つの画像ファイルにまとめて管理し、 必要な部分を切り出して表示するもの. 30
拡大してあげる const player = document.querySelector('div.style-scope.ytd-player'); const previewImg = document.querySelector('.ytp-storyboard-framepreview-img'); //
拡大率計算 const scaleX = player.clientWidth / previewImg.clientWidth; const scaleY = player.clientHeight / previewImg.clientHeight; // transform で拡大(左上基準で拡大) previewImg.style.transformOrigin = 'top left'; previewImg.style.transform = `scale(${scaleX}, ${scaleY})`; 31
余談: scrubbing-thumbnail シークバー下部では5×5 のstoryboard を最大100 枚使い2500 のシーク箇所を表示. 動画は最大12 時間(43200 秒)
なので約17 秒間隔でシーク箇所を表示することが可能. 32