YouTubeにパンコントロール機能を追加するChrome拡張を開発した


YouTubeのプレイヤーに直接UIを追加して音声のパンニング(左右の振り分け)を可能にするChrome拡張を作った。
■追記:現在はニコ生、OPENREC、SHOWROOMなど10以上のサイトに対応。

こんな感じで、なるべく画面に溶け込むように調整した。
ここからインストールできる。

目的と特徴

複数の配信を同時に見るときに、画面の位置と音の位置を同期させることによって聞き取りやすくなるような気がする。
プレイヤーに直接コントローラーを埋め込むことで、素早く&直感的に使えるようにした。

使ったもの

  • Content Scripts

    • これによって画面内に要素を追加できる。
  • Web Audio API

  • jQuery

    • 要素の追加とリスナーをシンプルに記述するために。

実装のポイント

動画の場合、音声ソースはvideo要素を指定する。

content-script.js
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const video = document.querySelector('video');
const audioSource = audioCtx.createMediaElementSource(video);

コントローラーは<input type="range">を使った。
rangeはデフォルトだと0〜100の値になっているのでmin='-1' max='1'としてあげることで、StereoPannerNodeに適した値を渡すことができる。

また、AudioContextはvideo要素が既にある状態でないと扱えないので、サイトによってタイミングの調性が必要になる。
大抵の場合はMutationObserverでなんとかなるが、backgroundのchrome.tabs.onUpdated.addListenerを使う方法もあるっぽい。

content-script.js

// 共通の関数
function setPan(html, point) {
    // スライドバーを挿入
    $(`${html}`).insertAfter(`${point}`);

    // オーディオノードをごにょごにょと繋げる
    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const video = document.querySelector('video');
    const audioSource = audioCtx.createMediaElementSource(video);
    const panNode = audioCtx.createStereoPanner();
    audioSource.connect(panNode);
    panNode.connect(audioCtx.destination);

     // スライドバーの動きに合わせて音声の位置を移動する
    $('input.pan-range').on("input", ()=> {
        const val = $(this).val();
        $(this).attr("value",val);
        panNode.pan.setValueAtTime(val, audioCtx.currentTime);
    });
}

// いい感じのタイミングでこれを発火
setPan("<input class='pan-range' type='range' min='-1' max='1' step='0.2' value='0'>", "サイトによって丁度いいところ");

反応を見る

Content Scriptsは見た目のインパクトが強いから、ちょっとした機能でも反応が貰える。
画像つきでツイートするといい。

あとは、リツイート直後のツイートを表示するやつを使うと、間接的な言及も拾える。

実は初めてChrome拡張作ったんだけど、数時間の作業で「神」とか言われるからすごい。無料だからお賽銭は貰えないけど。