Youtube用chrome拡張作ってハマったとこ

前置き

最近 Vtuber にドはまりしており、その影響で Youtube 用 chrome 拡張を自作しました。

Vtuber あんまり見ない人向けにも分かるように言うと、配信している Vtuber の知り合いがチャットを残した際にそれを画面に残してくれる拡張です。
ちょこちょこ同じ事務所の Vtuber が配信に来たりするんですが、作業しながら動画を流したりしてると

〇〇が来た!
〇〇もよう見とる
〇〇おるやんけ!

みたいなチャットに流されちゃって、そのチャットが見れなくて悔しい思いすることがあるんですよね……
配信してる Vtuber 自身もそのチャットに反応したりするので、見逃さなくなるのは我ながら本当に助かるツールです。

以下本編

iframe 内 document 使いたい問題

1
2
const chatFrame = document.getElementById('chatframe');
const chatFrameDocument = chatFrame.contentWindow.document; // iframe内文書の document

Youtube のチャット欄は iframe のため document からはアクセス不能。
普通に getElementById で取得してから contentWindow.document で取得できます。

初歩的な話ですが getElemetById と jQuery の\$(‘chatframe’)は取得するオブジェクトが異なるので注意

1
2
3
// これは動かない!
const chatFrame = $('#chatframe');
const chatFrameDocument = chatFrame.contentWindow.document; // iframe内文書の document

$(要素).on(‘load’, ()=>{})でも要素が取れない問題

1
2
3
4
5
6
7
8
9
10
// インターバルIDの取得
const setIntervalId = setInterval(startObserve, 1000);

function startObserve() {
if ($('#chatframe').length) {
clearInterval(setIntervalId); // setInterval解除

// #chatframeを取得後に行いたい処理を記述
}
}

Youtube チャット欄の iframe は遅延ロードされてるようで、iframe 自体の id を指定しても要素が取れませんでした。
jQuery の onload を使ってみても取得できなかったため、上記の実装で対応。

上記の実装では setInterval によって 1 秒ごとに startObserve 関数が呼ばれ、
#chatframe が見つかった時点で setInterval を停止させています。

遷移時に Content Scripts が読み込まれない問題

Youtube 拡張最後の罠。
動画再生ページで Content Scripts が動くように manifest.json を記述したのに、
画面更新しないと Content Scripts が読まれない場合があります。
理由は画面遷移時に画面更新が行われていないためでした。

その場合は manifest.json に以下の記述を追加。

1
2
3
"permissions":[
"https://www.youtube.com/watch?*", "tabs", "webNavigation"
],

その上で background.js に以下を記述

1
2
3
chrome.webNavigation.onHistoryStateUpdated.addListener(() => {
chrome.tabs.executeScript(null, { file: 'scripts/contentscript.js' });
});

これで画面遷移時に更新が行われなくても HistoryAPI を見て file に指定した js を呼んでくれるみたいです。
正直ここの実装はあまりちゃんと調べてないので詳しくは分かりませんが……

まとめ

DOM 拾って固定するだけなら簡単やろ!と思って作り始めた chrome 拡張でしたが、思ったよりハマりポイントが多かったです。
フロント詳しい人にとっては初歩的なことが多いかもしれませんが、ちょっとかじったレベルだと割とハマりやすい箇所かと思います。

みんなも chrome 拡張使って快適に Vtuber の配信見よう!以上!

参考 URL