LoginSignup
11
4

More than 3 years have passed since last update.

はじめに

前回、「Web Video Player, VideoJSの紹介」を投稿しました。
今回はVideoJS内部Componentという解釈と簡単の作成チュートリアルを記事したいと思います。

VideoJS Componentとは

VideoJSにある、全部のコントロールやUIなどはComponentというからクラス継承されています。
デフォルトの設計でComponentを継承して、さまさまのComponentを作成しました。

Player
├── MediaLoader (has no DOM element)
├── PosterImage
├── TextTrackDisplay
├── LoadingSpinner
├── BigPlayButton
├── LiveTracker (has no DOM element)
├─┬ ControlBar
│ ├── PlayToggle
│ ├── VolumePanel
│ ├── CurrentTimeDisplay (hidden by default)
│ ├── TimeDivider (hidden by default)
│ ├── DurationDisplay (hidden by default)
│ ├─┬ ProgressControl (hidden during live playback, except when liveui: true)
│ │ └─┬ SeekBar
│ │   ├── LoadProgressBar
│ │   ├── MouseTimeDisplay
│ │   └── PlayProgressBar
│ ├── LiveDisplay (hidden during VOD playback)
│ ├── SeekToLive (hidden during VOD playback)
│ ├── RemainingTimeDisplay
│ ├── CustomControlSpacer (has no UI)
│ ├── PlaybackRateMenuButton (hidden, unless playback tech supports rate changes)
│ ├── ChaptersButton (hidden, unless there are relevant tracks)
│ ├── DescriptionsButton (hidden, unless there are relevant tracks)
│ ├── SubtitlesButton (hidden, unless there are relevant tracks)
│ ├── CaptionsButton (hidden, unless there are relevant tracks)
│ ├── SubsCapsButton (hidden, unless there are relevant tracks)
│ ├── AudioTrackButton (hidden, unless there are relevant tracks)
│ ├── PictureInPictureToggle
│ └── FullscreenToggle
├── ErrorDisplay (hidden, until there is an error)
├── TextTrackSettings
└── ResizeManager (hidden)

目標

VideoJS ControlBarにあるCustomButton Componentというボタンを付属して、
そのボタンを押すと外部関数を走るようにします。

このようなのものです

example.gif

Github Repo: https://github.com/tokidoki11/video-js-component
このRepoではNuxtJSを使っていますが、NuxtJS知識は要りません。
本記事ではVideoJS Componentを中心にして、そのことだけを記事します。

実践

CustomButton作成

以下のコードご覧ください。解釈は後につけています

import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js'
const Button = videojs.getComponent('Button')


const iconSVG = `
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" fill="currentColor" viewBox="0 0 20 16">
<path d="M17.218,2.268L2.477,8.388C2.13,8.535,2.164,9.05,2.542,9.134L9.33,10.67l1.535,6.787c0.083,0.377,0.602,0.415,0.745,0.065l6.123-14.74C17.866,2.46,17.539,2.134,17.218,2.268 M3.92,8.641l11.772-4.89L9.535,9.909L3.92,8.641z M11.358,16.078l-1.268-5.613l6.157-6.157L11.358,16.078z"></path>
</svg>
`

interface CustomButtonOption extends VideoJsPlayerOptions{
  onClick: () => void
}

export default class CustomButton extends Button {
  constructor(
    player: VideoJsPlayer,
    options: CustomButtonOption
  ) {
    super(player, options)
    this.controlText("My Custom Button")
    this.el().innerHTML = iconSVG
  }

  handleClick(){
    (this.options_ as CustomButtonOption).onClick()
  }

  createEl(): HTMLButtonElement {
    return super.createEl('button', {
      className: 'vjs-custom'
    })
  }
}

解釈

1. Extending Button Component

今回はButtonComponentをもとに自作CustomButton Componentを作成します。
videojs.getComponentにComponent名を指定したら、Class Templateを取得します。

const Button = videojs.getComponent('Button')

取得してからベースクラスにして、継承を行います。

export default class CustomButton extends Button

2. Optionを展開する

基本的にはComponentをextendする時には2つの引数が示さなければなりません。
VideoJSPlayerとVideoJSOption。VideoJSOptionを展開して、onClick関数をもらえるようにします。

interface CustomButtonOption extends VideoJsPlayerOptions{
  onClick: () => void
}
constructor(
    player: VideoJsPlayer,
    options: CustomButtonOption
  )

handleClick関数をオーバーライドして、optionにあるonClickを実行するように

handleClick(){
    (this.options_ as CustomButtonOption).onClick()
}

3. Styling

Elementを作成します、createEl関数にParent ClassのcreateElを実行して。
<button class="vjs-custom"></button>が作成されるように

  createEl(): HTMLButtonElement {
    return super.createEl('button', {
      className: 'vjs-custom'
    })
  }

SVGアイコンを用意します

const iconSVG = `
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" fill="currentColor" viewBox="0 0 20 16">
<path d="M17.218,2.268L2.477,8.388C2.13,8.535,2.164,9.05,2.542,9.134L9.33,10.67l1.535,6.787c0.083,0.377,0.602,0.415,0.745,0.065l6.123-14.74C17.866,2.46,17.539,2.134,17.218,2.268 M3.92,8.641l11.772-4.89L9.535,9.909L3.92,8.641z M11.358,16.078l-1.268-5.613l6.157-6.157L11.358,16.078z"></path>
</svg>`

文言とSVGアイコンをボタンにつけます

constructor(
    player: VideoJsPlayer,
    options: CustomButtonOption
  ) {
    super(player, options)
    this.controlText("My Custom Button") //これはボタンTitleです
    this.el().innerHTML = iconSVG //ボタンElementのなかにSVGを付属する
  }

VideoJSにつけたあるCustomButtonを作成

以下のコードご覧ください。解釈は後につけています

<template>
  <div id="video-player-component">
    <h1>I'm counting: {{count}}</h1>
    <video
      ref="videoPlayer"
      class="video-js vjs-show-big-play-button-on-pause vjs-big-play-centered"
      muted
    />
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import videojs, { VideoJsPlayerOptions } from 'video.js'
import CustomButton from '@/video-components/customButton'

videojs.registerComponent('CustomButton', CustomButton)

const videoConfig = {
  autoplay: true,
  controls: true,
  html5: {
    vhs: {
      allowSeeksWithinUnsafeLiveWindow: true,
      enableLowInitialPlaylist: true,
      overrideNative: false,
      smoothQualityChange: true,
      withCredentials: false
    }
  },
  inactivityTimeout: 0,
  sources: [{
    src: "https://live.unified-streaming.com/scte35/scte35.isml/.m3u8",
    type: 'application/x-mpegURL'
  }],
  liveui: true,
  muted: true,
  preload: 'auto',
  width:720
} as VideoJsPlayerOptions

export default Vue.extend({
  data:()=>{
    return {
      count : 0
    }
  },
  mounted(){
    const videoPlayer = this.$refs["videoPlayer"]
    const player = videojs(videoPlayer, videoConfig, ()=>{
      player.controlBar.addChild("CustomButton", {
        onClick:()=>{
          this.count++
        }
      })
    })
  }
})
</script>
<style>
.vjs-custom{
  cursor: pointer;
  font-size: 1.8em!important;
  color:white;
}
</style>

解釈

1. Import CustomButton Class
CustomButtonをImportして

import CustomButton from '@/video-components/customButton'

その後videoJSにComponentを紹介します。
引数1: Component name (好みで)
引数1: Component class

videojs.registerComponent('CustomButton', CustomButton)

2. VideoJS Instanceを作成

 const videoPlayer = this.$refs["videoPlayer"]
 const player = videojs(videoPlayer, videoConfig, ()=>{
 ...

3. VideoJS PlayerのControlBarにCustomButtonを追加

addChild関数には3つの引数を受けます
引数1: Component Name
引数2: Option(今回は CustomButtonOption Interfaceに参考)
引数3: 順番(なければ後ろに)

このonClickではdataにあるcountを加算してます。

player.controlBar.addChild("CustomButton", {
  onClick:()=>{
    this.count++
  }
})

最後

このチュートリアルは終了になります。
色々VideoJS Componentがありまして、Extend方法も多少違っています。
Button ComponentにはhandleClickがありますが、他にはそうでもないでしょう。

基本的には同じ流れになります。

この記事が役に立つなるように

参考に

11
4
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
11
4