VideoPlayer.vue 6.18 KB
Newer Older
Anton's avatar
Anton committed
1
<template lang="pug">
Anton Koch's avatar
Anton Koch committed
2
  vue-video-player(:class="classConfig",
Anton's avatar
Anton committed
3 4 5 6 7 8 9 10 11 12 13 14 15
    ref="videoPlayer",
    :options="playerOptions",
    :playsinline="true",
    customEventName="customstatechangedeventname",
    @play="onPlayerEvent('play', $event)",
    @pause="onPlayerEvent('pause', $event)",
    @ended="onPlayerEvent('ended', $event)",
    @waiting="onPlayerEvent('waiting', $event)",
    @playing="onPlayerEvent('playing', $event)",
    @loadeddata="onPlayerEvent('data', $event)",
    @timeupdate="onPlayerEvent('time', $event.currentTime())",
    @canplay="onPlayerEvent('canplay', $event)",
    @canplaythrough="onPlayerEvent('canplaythrough', $event)",
Anton's avatar
Anton committed
16
    @statechanged="onPlayerStateChange($event)",
Anton's avatar
Anton committed
17 18 19 20 21 22 23 24 25 26 27 28 29
    @ready="onPlayerReady")
</template>

<script>
  require('video.js/dist/video-js.css')
  require('vue-video-player/src/custom-theme.css')
  require('videojs-youtube')
  require('videojs-framebyframe')

  require('videojs-vimeo/src/Vimeo')
  import { videoPlayer } from 'vue-video-player'
  import guessType from 'mbjs-media/src/util/guess-type'

Anton Koch's avatar
Anton Koch committed
30 31
  if (process.env.FEATURE_BETWEENUS) require('./videojs-betweenus.styl')

Anton's avatar
Anton committed
32 33 34 35 36 37 38
  export default {
    components: {
      'vue-video-player': videoPlayer
    },
    data () {
      return {
        type: undefined,
Anton Koch's avatar
Anton Koch committed
39 40 41 42 43 44
        classConfig: {
          'video-player': true,
          'video-player-box': true,
          'vjs-big-play-centered': true,
          'vjs-betweenus': process.env.FEATURE_BETWEENUS
        },
Anton's avatar
Anton committed
45 46 47 48 49 50 51 52 53 54
        playerOptions: {
          fluid: true,
          autoplay: this.autoplay,
          width: 640,
          techOrder: ['html5'],
          language: 'en',
          playbackRates: this.playbackRates ? [0.25, 0.5, 1.0, 1.5, 2.0] : undefined,
          sources: [],
          poster: undefined,
          controlBar: this.noControls ? undefined : {
Anton's avatar
Anton committed
55
            remainingTime: true,
56
            volumePanel: !this.noVolumePanel,
Anton's avatar
Anton committed
57
            fullscreenToggle: !this.noFullscreen
Anton's avatar
Anton committed
58
          },
59 60 61
          youtube: {
            enablePrivacyEnhancedMode: true
          },
62 63 64
          vimeo: {
            dnt: true
          },
Anton's avatar
Anton committed
65 66 67 68 69
          plugins: this.fineControls ? {
            // TODO: implement our own vesion of this to remove dependency
            framebyframe: {
              fps: 23.98, // FIXME: 25.0 ?!?, make "smart"
              steps: [
Anton's avatar
Anton committed
70 71 72 73
                { text: '-1s', step: -24 },
                { text: '-1f', step: -1 },
                { text: '+1f', step: 1 },
                { text: '+1s', step: 24 }
Anton's avatar
Anton committed
74 75 76 77 78 79
              ]
            }
          } : {}
        }
      }
    },
80
    props: ['src', 'annotation', 'autoplay', 'playbackRates', 'noControls', 'noFullscreen', 'noVolumePanel', 'fineControls'],
Anton's avatar
Anton committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    async mounted () {
      await this.getSource(this.src, this.annotation)
    },
    watch: {
      async src (val) {
        await this.getSource(val, this.annotation)
      },
      async annotation (val) {
        await this.getSource(this.src, val)
      },
      autoplay (val) {
        this.playerOptions.autoplay = val
      }
    },
    computed: {
      player () {
        return this.$refs.videoPlayer.player
      }
    },
    methods: {
      onPlayerReady (player) {
        this.$emit('ready', player)
      },
      async getSource (src, annotation = undefined) {
        if (!src && !annotation) return
        this.type = guessType(src || annotation.body.source.id)
        if (this.type === 'video/youtube') {
          this.playerOptions.techOrder = ['youtube']
        }
        else if (this.type === 'video/vimeo') {
          this.playerOptions.techOrder = ['vimeo']
        }
        else if (this.type === 'video/panopto' && annotation) {
          this.type = 'video/mp4'
115
          const meta = await this.$store.dispatch('metadata/get', annotation._uuid)
Anton's avatar
Anton committed
116 117 118 119 120 121 122 123 124 125 126 127 128
          if (meta && meta.video) src = meta.video
          else console.error('panopto video failed to load', meta.video)
        }
        if (!src && annotation) src = annotation.body.source.id
        this.setSources([{ type: this.type, src: src }])
      },
      onPlayerEvent (type, player) {
        this.$emit(type, player)
      },
      onPlayerStateChange (player) {
        this.$emit('state-change', player)
      },
      setSources (sources, poster = undefined) {
129 130 131 132
        if (!this.player) {
          const _this = this
          return setTimeout(() => _this.setSources(sources, poster), 100)
        }
Anton's avatar
Anton committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
        if (!Array.isArray(sources)) {
          sources = [sources]
        }
        if (poster) this.playerOptions.poster = poster
        if (!this.playerOptions.sources || !this.playerOptions.sources.length) {
          this.playerOptions.sources = sources
        }
        else {
          this.player.src(sources)
          this.player.load()
        }
      },
      reset () {
        this.$refs.videoPlayer.player.reset()
      }
    }
  }
</script>

<style lang="stylus">
Anton Koch's avatar
Anton Koch committed
153

Mathias Bär's avatar
Mathias Bär committed
154 155
  @import '~variables'

Anton Koch's avatar
Anton Koch committed
156 157 158 159 160 161 162 163
  .video-js
    font-family 'Roboto'
    position static !important

  .video-js .vjs-control-bar
    height 40px

  .video-js.vjs-paused .vjs-big-play-button
Mathias Bär's avatar
Mathias Bär committed
164
    background $primary
Anton Koch's avatar
Anton Koch committed
165 166 167 168 169 170 171 172 173 174 175
    width 66px
    height 66px
    line-height 66px
    border 0
    border-radius 33px

  .vjs-big-play-centered .vjs-big-play-button
    margin-top -33px
    margin-left -33px
    font-size 4em !important

Mathias Bär's avatar
Mathias Bär committed
176
  .vjs-big-play-centered .vjs-big-play-button .vjs-icon-placeholder:before
Anton Koch's avatar
Anton Koch committed
177 178
    line-height 65px !important

Mathias Bär's avatar
Mathias Bär committed
179
  .vjs-button > .vjs-icon-placeholder:before
Anton Koch's avatar
Anton Koch committed
180 181 182 183
    font-size 2.5em
    padding-top 1px

  .video-js .vjs-control-bar
Mathias Bär's avatar
Mathias Bär committed
184
    background-color $primary66
Anton Koch's avatar
Anton Koch committed
185 186 187 188

  .video-js .vjs-control-bar .vjs-slider
    background-color rgba(255,255,255,0.333)

Mathias Bär's avatar
Mathias Bär committed
189
  .video-js .vjs-control-bar .vjs-play-control .vjs-icon-placeholder:before
Anton Koch's avatar
Anton Koch committed
190 191
    line-height 40px

Mathias Bär's avatar
Mathias Bär committed
192
  .vjs-fullscreen-control .vjs-icon-placeholder:before
Anton Koch's avatar
Anton Koch committed
193 194 195 196 197 198 199 200 201 202 203 204
    line-height 40px

  .video-js .vjs-time-control
    font-size 0.85rem
    line-height 40px

  .video-js .vjs-progress-control
    padding-top 3px

  .video-js .vjs-progress-control .vjs-load-progress
    background-color rgba(255,255,255,0.333)

Mathias Bär's avatar
Mathias Bär committed
205
  .video-js .vjs-play-progress:before
Anton Koch's avatar
Anton Koch committed
206 207 208
    font-size 1.5em
    right -0.8em
    top -0.4em
209
    z-index 0
Anton Koch's avatar
Anton Koch committed
210 211 212 213

  /* Video.js scaling */

  .video-js .vjs-tech
christianrhansen's avatar
fixed  
christianrhansen committed
214
    /*height auto*/
Anton Koch's avatar
Anton Koch committed
215 216 217 218

  .video-js .vjs-tech
    border-right: 1px solid #111 !important
    border-bottom: 1px solid #111 !important
Anton's avatar
Anton committed
219
</style>