PC[動画(p5.js)→色情報(RGB)]→MQTT→M5→LED

PCのブラウザ上で再生する動画の「色」を、プログラムで読み取る準備をします。最終的には、この色をLEDに送ることで、音楽と光を同期させます。

Step1 PC側(p5.js):ブラウザ上で動画を再生する

まず、ウェブページ上に動画を表示させます。HTMLファイルでp5.jsを読み込み、JavaScriptファイル(sketch.js)で動画を操作します。

動画はそのまま表示せず、p5.jsのキャンバスという「お絵かきスペース」に描画することで、後で色情報を取得しやすいようにしています。

ファイル構成

このステップで使うファイルは、以下の2つです。

  • index.html: ウェブページの基本となるファイルです。p5.jsや、後で作成するsketch.jsを読み込みます。
  • sketch.js: p5.jsのプログラムを書くファイルです。ここに動画の読み込みや描画のコードを書いていきます。

同じフォルダに、再生したい動画ファイル(例:clip.mp4)も入れておきましょう。

フォルダ構造

step01_video_only
├── clip.mp4
├── index.html
└── sketch.js

コード

Index.html

コード(index.html)
<!doctype html>
<html lang="ja">
<head>
  <!-- 文字コードの指定(文字化け防止) -->
  <meta charset="utf-8" />
  <!-- モバイルでも見やすくするためのビューポート設定 -->
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Step1: Video only</title>

  <!-- p5.js(CDNから) -->
  <script src="https://cdn.jsdelivr.net/npm/p5@1.10.0/lib/p5.min.js"></script>

  <!-- 最初の練習なのでCSSやUIは最小限 -->
  <style>
    body { margin: 0; font: 14px/1.4 system-ui; }
    #hint {
      position: fixed; left: 8px; top: 8px;
      background: #0008; color: #fff; padding: 8px; border-radius: 8px;
    }
  </style>
</head>
<body>
  <!-- p5のcanvasは<body>直下に作られます -->
  <script src="./sketch.js"></script>
</body>
</html>
コード解説

body { margin: 0; ... }:
画面の端にある余白(マージン)を消しています。p5.jsの作品を画面いっぱいに表示したい場合によく使う設定です。

sketch.js

コード(sketch.js)
/// グローバル変数として、動画オブジェクトを格納する変数を用意
let vid; 

// 動画を読み込むための特別な関数
function preload(){
  // "clip.mp4"という動画ファイルを読み込んで、vidという変数に保存します。
  // ここで読み込んだ動画は、まだ画面には表示されません。
  vid = createVideo("clip.mp4");
}

// プログラムが始まったときに一度だけ実行される関数
function setup(){
  // 320x240ピクセルの「キャンバス」を作ります。
  createCanvas(320, 240);
  
  // 動画の大きさを320x180ピクセルに設定します。
  vid.size(320, 180);
  
  // 元の動画(HTMLのvideoタグ)を画面から隠します。
  // これで、p5.jsのキャンバス上でだけ動画を扱えるようになります。
  vid.hide();
  
  // 動画を繰り返し再生するように設定します。
  vid.loop();
}

// 1秒間に約60回、繰り返し実行される関数
function draw(){
  // キャンバス全体を黒っぽい色で塗りつぶします。
  background(20);
  
  // **ここで、`vid`変数に保存された動画をキャンバスに描画します。**
  // これにより、動画の内容が画面に表示されます。
  image(vid, 0, 0);
}

// マウスがクリックされたときに実行される関数
function mousePressed(){
  // 動画の音を出すように設定します。
  // マウスをクリックすると、動画の音声が聞こえるようになります。
  vid.elt.muted = false;
}
コード解説

このプログラムは、パラパラ漫画のような仕組みで動いています。

  1. 裏で動画プレイヤーを再生する。
  2. その動画プレイヤーの「今この瞬間のコマ」をコピーする。
  3. キャンバスに貼り付ける(これを秒間60回繰り返す)。
1. 準備 (preload)
function preload() {
    vid = createVideo("clip.mp4");
}
  • なぜ preload を使う?:
    • setup() の中で読み込むと、動画のデータが重い場合、読み込み終わる前にプログラムが進んでしまいエラーになることがあります。
      preload に書くと、「動画の読み込みが完全に終わるまで、次の setup に進まない」 という待機保証をしてくれます。
2. 設定 (setup)
function setup() {
    createCanvas(320, 240);
    vid.size(320, 180);
    vid.hide(); // ★ここが重要
    vid.loop();
}
  • vid.hide() の意味:
    • p5.jsで createVideo をすると、キャンバスとは別に、HTMLの標準的な <video> タグ(動画プレイヤー)が画面下に追加されてしまいます。
      • そのままだと「キャンバス」と「動画プレイヤー」の2つが表示されて邪魔です。
      • vid.hide() を使うことで、「動画プレイヤー(DOM要素)は見えなくするけれど、裏で再生はしておく」 という状態にします。
3. 描画ループ (draw)
function draw() {
    background(20);
    image(vid, 0, 0);
}
  • なぜ image() を使うのか?:
    • この行は、裏で再生されている動画の「今この瞬間の1コマ」を写真としてキャンバスに焼き付けています。
    • キャンバス(画用紙)に描かれた「絵」になることで、次のステップ(Step 2)で登場する get(x, y) 関数を使って、「画面中央の色は何色?」と調べることが可能になります
    • もし普通の <video> タグで再生しているだけだと、プログラムで色を覗き見ることができません。
4. 操作 (mousePressed)
function mousePressed() {
    vid.elt.muted = false;
}
  • なぜクリックで音を出す?:
    • 現代のWebブラウザ(ChromeやSafariなど)は、「ユーザーが何か操作(クリックなど)をする前に、勝手に音が出る動画を再生すること」を禁止しています(Autoplay Policy)。
    • そのため、ユーザーがクリックしたタイミングでミュートを解除する、という手順が必要になる可能性があります(そのままうまく再生される場合もある)。

動作確認

このコードを実行すると、HTMLファイルと同じフォルダにある音楽付きの動画ファイルがブラウザの画面に表示され、自動で再生 or マウスをクリックすると音声が再生されるはずです。

このコードは、一見ただ動画を再生しているだけに見えますが、裏では「動画データ(閲覧用)」を「画像データ(解析用)」に変換し続けている状態です。

この処理が動いているからこそ、次のステップで:

  1. draw() の中で get() を使い、
  2. その色を MQTT で M5StickC に飛ばし、
  3. LED を光らせる

という連携が可能になります。

※ 動画はTextAliveを活用して作成させていただきました!音楽情報を活用してエフェクトを自動生成してくれます(土田が元配属されていた研究グループのサービスです)。是非使ってみてください。
※ 動画について詳しくは最後のページに載せました。