GameWith Developer Blog

GameWith のエンジニア、デザイナーが技術について日々発信していきます。

動画の操作のログを送信する #GameWith #TechWith

はじめに

こんにちは。GameWith のエンジニアの tiwu です!

この記事は GameWith アドベントカレンダーの 8 日目の記事になります!

qiita.com

今回は video タグで再生される動画の操作ログの取得方法について書いていこうと思います。

動画のログについて

button タグなどのクリックのログであれば対象のタグに対して addEventListenerclick イベントを付与しログの送信を行うことが多いです。

しかし video タグ内にある再生、音量、シークなどの各機能を制御する UI に対して addEventListenerclick イベントの付与をすることはできません。

f:id:tiwu:20211122121919p:plain

そのため動画に関するログを送信する場合は、video タグが発生させるイベントを利用しログの送信を行います。

developer.mozilla.org

紹介するイベントは最大化(fullscreenchange)を除き、 video タグの継承元である HTMLMediaElement のイベントになります。

developer.mozilla.org

再生

動画が再生した際に play イベントが発火します。

developer.mozilla.org

発火するタイミングは主に

  • autoplay プロパティによる自動再生
  • 停止後、再生が行われた時
  • 終了後、再生が行われた時

があります。

サンプルコード

const videoElement = document.querySelector("video");
let isEnd = false;
let isPause = false;
videoElement.addEventListener("play", () => {
  if (isEnd) {
    console.log("動画終了後に再生");
  } else if (isPause) {
    console.log("停止後に再生");
  } else {
    console.log("自動再生");
  }

  isPause = false;
  isEnd = false;
});

videoElement.addEventListener("pause", () => {
  isPause = true;
});

videoElement.addEventListener("ended", () => {
  isEnd = true;
});

autoplay プロパティによる自動再生

autoplay プロパティを利用すると自動で動画が再生されます。

developer.mozilla.org

autoplay による自動再生か判断するのは難しいですが後述する他のイベントを判断することで、自動再生か判断します。

停止後、再生が行われた時

pause イベントが必ず発生後に、play イベントが発火するため変数を利用し判断しています。

終了後、再生が行われた時

ended イベントが必ず発生するため、停止後と同様に変数を利用し判断しています。

終了後の再生は currentTime プロパティが必ず 0 になっており、自動再生ではネット環境の影響か 0 になることは筆者の環境ではありませんでした。

そのため currentTime プロパティで判断することもできそうです。

developer.mozilla.org

※自動再生による再生で 0 以外になるかは確証がないため参考程度に読んでもらえればと🙏

videoElement.addEventListener("play", () => {
  if (videoElement.currentTime === 0) {
    console.log("動画終了後に再生");
  }
});

停止

動画が停止した際に pause イベントが発火します。

developer.mozilla.org

発火するタイミングは主に

  • 停止した時
    • 停止 UI のクリック
    • pause メソッドの実行で停止した時
  • 終了した時

があります。

サンプルコード

const videoElement = document.querySelector("video");
videoElement.addEventListener("pause", () => {
  if (videoElement.ended) {
    console.log("動画終了したため停止");
  } else {
    console.log("停止");
  }
});

この2つのタイミングは ended プロパティにより判断します。

developer.mozilla.org

停止した時

停止時の pause イベント内では ended プロパティは false になっているのを利用し判断します。

終了した時

動画が終了した際は pauseended の順にイベントが発火します。

終了時の pause イベント内では ended プロパティは true になっているのを利用し判断します。

終了

動画が終了した際に ended イベントが発火します。

developer.mozilla.org

サンプルコード

const videoElement = document.querySelector("video");
videoElement.addEventListener("ended", () => {
  console.log("動画終了");
});

終了以外のタイミングで発火しないため特に制御なしで実装しています。

音量

動画の音量が変化した際に volumechange イベントが発火します。

developer.mozilla.org

サンプルコード

const videoElement = document.querySelector("video");
videoElement.addEventListener("volumechange", () => {
  if (videoElement.muted === true) {
    console.log("音声が on -> off");
  }
});

音量が ON の状態から OFF に変更した際は mutedtrue になっているのを利用し判断します。

最大化

動画を最大化した際に video タグではイベントは発火せず、Documentfullscreenchange イベントが発火します。

developer.mozilla.org

サンプルコード

const fireFullScreenChange = () => {
  const fullScreen =
      document.fullscreenElement ||
      document.mozFullScreenElement ||
      document.webkitFullscreenElement ||
      document.msFullscreenElement;
  if (fullScreen && fullScreen.classList.contains("video")) {
    console.log("動画が最大化");
  }
};

document.addEventListener(
  "webkitfullscreenchange",
  fireFullScreenChange
);
document.addEventListener(
  "mozfullscreenchange",
  fireFullScreenChange
);
document.addEventListener(
  "MSFullscreenChange",
  fireFullScreenChange
);
document.addEventListener(
  "fullscreenchange",
  fireFullScreenChange
);

このイベントは Document で発生するため、最大化した要素が指定の要素か判断するために document.fullscreenElement を利用します。

developer.mozilla.org

サンプルコードでは最大化した要素に video クラスがあるか判定しています。

余談

このブログを書いている際に調べていて気づいたのですが Element でも fullscreenchange は発生するようで、requestFullscreen を利用すれば div タグなども全画面にすることができるそうです 👀

developer.mozilla.org

終わりに

MDN の公式を読んでいるといろいろな便利なイベントやメソッドがあり、直接クリックでログを仕込めなくても工夫しログを送信することができました✌️

この記事が何かの参考になればと思います!

Twitter

Twitter にてテックブログの投稿をツイートしていますので、よろしければフォローをお願いします!

twitter.com

Wanted!

一緒に働く仲間(特にサーバサイドエンジニア)を絶賛募集中です!

以下 Wantedly のページからぜひカジュアル面談へお申し込みください!

www.wantedly.com