1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

vue.jsとhls.jsでスクロールして動画が画面上にある時にだけ動画を再生したい

Posted at

vue.jsとhls.jsで動画を再生させる基礎
https://qiita.com/asa1084/items/07195a77762e345abb7a

<template>
  <div>
    <div style="margin-bottom: 1000px"></div>
    <video id="video" controls muted playsinline loop width="300px"></video>
    <div style="margin-bottom: 1000px"></div>
  </div>
</template>
<script>
import Hls from "hls.js";

export default {
  data: () => {
    return {
      hls: null,
      isPlaying: false,
      screenHeight: 0,
    };
  },

  methods: {
    playVide() {
      const video = document.getElementById("video");

      // ビデオの現在の位置を取得
      const videoTop = video.getBoundingClientRect().top;

      const videoUrl =
        "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8";

      // ビデオ位置(高さ200込み)が画面サイズに収まっている場合 ※高さ200は仮です
      if (this.screenHeight - (videoTop + 200) > 0 && videoTop + 200 > 0) {
        // 再生中の場合何もしない
        if (this.isPlaying) return;

        // 再生中はplayVideを無効化
        this.isPlaying = true;

        // 動画を取得済の場合は再生処理のみ行う
        if (this.hls != null) {
          video.play();
          return;
        }

        // 終了時、再度再生できるようにする。
        video.addEventListener("ended", (event) => {
          this.isPlaying = false;
        });

        if (Hls.isSupported()) {
          this.hls = new Hls();
          this.hls.loadSource(videoUrl);
          this.hls.attachMedia(video);
          video.play();
        } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
          video.src =
            "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8";
          video.addEventListener("canplay", () => {
            video.play();
          });
        }
      } else {
        // 再生中の場合、ビデオを停止
        if (this.isPlaying) {
          video.pause();
          this.isPlaying = false;
        }
      }
    },
  },
  mounted() {
    // scrollすると動画再生関数発火
    window.addEventListener("scroll", () => {
      this.playVide();
    });

    // 画面の縦のサイズを取得
    this.screenHeight = window.innerHeight;
  },
  computed: {},
  beforeDestroy() {
    window.removeEventListener("scroll", () => {
      this.playVide();
    });
  },
};
</script>

<style scoped>
</style>

解説していきます。

まず動画が画面をスクロールするとmounted内にあるaddEventListenerが呼ばれます。
addEventListenerではvideoを再生する関数を実行させます。

methodsないで動画を再生させる関数videoPlayを定義。

画面上に動画がある時だけ再生させる必要がりますが、デバイスによって画面の大きさが変わるので、動的に決めていく必要があります。

window.innerHeight で画面のたての高さが取得できる。

video.getBoundingClientRect().top()で動画の一番上を取得できます。
詳しいgetBoundingClientRectの使い方は[こちら]
(https://ja.javascript.info/coordinates)

上記を使ってどこに動画がある時に動画再生スタートさせるか決めます。

addEventListenerのendedで動画の再生が終わった時にbooleanを渡してくれます。
なので、動画再生が終わるとisPlayをfalseにしてまたスクロールされると動画が再生されるようにします。

vue.jsはシングルページアプリケーションなので
window.addEventListenerを使っていないページでもaddEventListenerが呼ばれてしまいます。
メモリを食う!ページ高速化のためにも必ずbeforeDestroyで他の箇所では呼ばれないようにしましょう。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?