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
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
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.2k
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.7k
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.9k
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
260
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
450
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
180
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
550
Are APIs Still Relevant in the AI Era?
soyuka
0
290
iOSDC2026登壇資料.pdf
riofujimon
0
170
Jetpack Compose メカニズム
skydoves
0
460
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
370
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
560
Featured
See All Featured
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
58k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Designing Experiences People Love
moore
143
24k
ラッコキーワード サービス紹介資料
rakko
1
5M
Fireside Chat
paigeccino
43
4k
Producing Creativity
orderedlist
PRO
348
41k
What's in a price? How to price your products and services
michaelherold
247
13k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Exploring anti-patterns in Rails
aemeredith
4
510
The SEO identity crisis: Don't let AI make you average
varn
0
560
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
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